本次基于webpack@5.54.0, 完成相关 webpack 优化,具体相关配置参数请查看官网
核心包:
webpack
,webpack-cli
,webpack-dev-server
,html-webpack-plugin
,@babel/core
,@babel/preset-env
,babel-loader
,clean-webpack-plugin
防止 webpack 解析那些任何与给定正则表达式相匹配的文件。忽略的文件中不应该含有 import, require, define 的调用,或任何其他导入机制。忽略大型的 library 可以提高构建性能。
所以总的结论是: 文件中没有任何导入就可以使用 noParse
列子:引用 jquery 时,使用 noParse 加快打包速度 1
module: {
noParse: /jquery|lodash/,
}
忽略第三方包中的一些不使用的文件,减少打包体积
moment.js 举例, 去除 webpack 中其他语言包,只导入之际所需要的语言包
660KB
2.14MB
1.01M
/* webpack.config.js */
const webpack = require('webpack')
module.exports = {
...,
plugins: [
new webpack.IgnorePlugin({
resourceRegExp: /^\.\/locale$/,
contextRegExp: /moment$/,
})
]
}
/* index.js中使用momentjs */
import * as moment from 'moment';
import 'moment/locale/zh-cn';
console.log(moment.locale('zh-cn'));
console.log(moment(1316116057189).fromNow());
动态链接库好处:减小入口文件大小,比如减小 index.js 文件大小,避免首屏加载过慢。单独打包了第三方库文件,加快了打包编译速度。但动态链接库的使用不一定会整体减少构建包的体积。
分别以 react 和 vue 来举例
三个核心包:
react
,react-dom
,@babel/preset-react
/* 主要在babel presets添加对@babel/preset-react 解析react语法*/
/* .babelrc */
{
"presets": [
[
"@babel/preset-env",
{
"targets": "defaults"
}
],
[
"@babel/preset-react",
{
"targets": {
"node": "current"
}
}
]
]
}
1: /* 新建打包第三方的webpack配置文件 */
/* webpack.config.react.js 生产json清单路径*/
module.exports = {
plugins: [
new webpack.DllPlugin({
name: '_dll_[name]',
path: path.resolve(__dirname, "dist", "manifest.json"),
})
]
}
2: /* 主配置文件 */
/* webpack.config.js 该去那里查找清单路径*/
new webpack.DllReferencePlugin({
manifest: path.resolve(__dirname, "dist", "manifest.json"),
})
/* CleanWebpackPlugin设置cleanOnceBeforeBuildPatterns属性,每次打包不会清空dll文件夹下文件,避免每次都打包第三方库 */
new CleanWebpackPlugin({
cleanOnceBeforeBuildPatterns: ["**/*", "!dll/**"],
}),
3: /* index.html 引入打包后的第三方js */
<script src="./_dll_react.js"></script>
构建包体积 | 入口文件大小 | 第三方打包文件大小 |
---|---|---|
126kb | 125kb | / |
129kb | 小于 1KB | 128kb |
构建包体积 | 入口文件大小 | 第三方打包文件大小 |
---|---|---|
64.1kb | 63.7kb | / |
65.0kb | 小于 1KB | 64.1kb |
开启多线程打包,加快打包构建速度。
/* webpack.config.js */
module.exports = {
rules: [
rules: [{
test: /\.m?js$/,
exclude: /node_modules/,
use: "happypack/loader",
}]
plugins: [
new HappyPack({
threads: 4,
loaders: ["babel-loader"],
}),
]
}
把没用的代码自动删除
/* unit.js */
const sum = (a, b) => {
return a + b;
};
const minus = (a, b) => {
return a - b;
};
export default {
sum,
minus,
};
/* index.js */
import calc from "./utils.js";
console.log(calc.sum(1, 2));
打包后 webpack 会自动去掉 minus 函数,因为它没有被调用过
在 webpack 中自动省略部分代码,计算数值,简化代码。
let a = 1;
let b = 2;
let c = 3;
let d = a + b + c;
console.log(d + "------");
经过 webpack 打包后,会自动计算出结果,打包文件会直接输出 console.log(6+'------')
。
从 webpack v4 开始,移除了 CommonsChunkPlugin,取而代之的是 optimization.splitChunks
新建三个文件, app1.js
, app2.js
, common.js
。app1 和 app2 都导入了 common, 如果不采用抽离公共代码,打包后,app1 和 app2 都会包含 common 的代码。
其实此时,我们即可将 common 抽离为公共代码块,进行单独打包为一个文件,app1 和 app2 只需引入公共代码块,增加代码的可复用性。
具体操作如下:
/* 具体配置参数查看webpack官网 */
module.exports = {
optimization: {
splitChunks: {
cacheGroups: {
common: {
// filename: "common.js",
name: "commons",
chunks: "initial",
minChunks: 2,
minSize: 0,
},
},
},
},
};
提示:在代码复用性不高,公共代码不多时使用抽离公共代码,反而会增加构建包的体积。例如本例中,
公共代码块很简单,体积不大,不需要剥离代码块,剥离后反而增加了构建包的体积。
/* 具体配置参数查看webpack官网 */
module.export = {
optimization: {
splitChunks: {
cacheGroups: {
commons: {
name: "chunk-common",
chunks: "initial",
priority: -20,
minChunks: 2,
minSize: 0,
},
vendors: {
name: `chunk-vendors`,
test: /[\\/]node_modules[\\/]/,
priority: -10,
chunks: "initial",
},
},
},
},
};
下图是 vuecli4 脚手架的 SplitChunksPlugin 配置。
我们可以修改该配置,将 chunk-vendors 进一步剥离,以优化我们的首频加载速度。例如,我们可以将第三方组件库单独剥离出来,具体配置如下:
/* vue.config.js vuecli4.0 */
module.exports = {
configureWebpack: (config) => {
config.optimization = {
splitChunks: {
cacheGroups: {
/* 将node_modules下依赖包单独打包 */
vendors: {
name: "chunk-vendors",
test: /[\\/]node_modules[\\/]/,
priority: -10,
chunks: "initial",
},
common: {
/* 将复用两次以上的方法单独打包 */
name: "chunk-common",
minChunks: 2,
priority: -20,
chunks: "initial",
reuseExistingChunk: true,
},
/* 将vant 单独打包 */
vant: {
chunks: "all",
name: `vant`,
test: /[\\/]vant[\\/]/,
priority: 0,
},
},
},
};
},
};
使用 SplitChunks 插件来剥离公共代码块单独打包有利有弊,好处在于,防止模块被重复打包,拆分过大的 js 文件,合并零散的 js 文件。缺点即为剥离越彻底,打包后的文件越多,增加浏览器的请求次数,故要以项目实际的情况去使用 SplitChunks 插件,需切记中庸之道。
参考文献:webpack 之 SplitChunks 插件用法详解
es6 草案中的语法,jsonp 实现动态加载文件。如 vue 路由懒加载,react 懒加载都是采用的这种方式。
/* 主要代码 */
/* source.js */
export default "我是资源文件";
/* index.js */
import("./source.js").then((data) => {
console.log(data.default);
});
webpack5 默认支持 HRM
在开发环境,可以将 HMR 作为 LiveReload 的替代。webpack-dev-server 支持 hot 模式,在试图重新加载整个页面之前,hot 模式会尝试使用 HMR 来更新。
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。