Webpack 实践 - optimization.splitChunks
默认值
默认情况下,SplitChunksPlugin
只会影响到按需加载的 chunks
。
webpack
将根据以下条件自动拆分 chunks
:
- 新的 chunk 可以被共享,或者模块来自于 node_modules 文件夹
- 新的 chunk 体积大于 20kb(在进行 min+gz 之前的体积)
- 当按需加载 chunks 时,并行请求的最大数量小于或等于 30
- 当加载初始化页面时,并发请求的最大数量小于或等于 30
module.exports = {
//...
optimization: {
splitChunks: {
chunks: 'async',
minSize: 20000, // 分割代码应满足的最小体积
minRemainingSize: 0,
minChunks: 1,
maxAsyncRequests: 30, // 按需加载时并行加载的文件的最大数量
maxInitialRequests: 30, // 入口点的最大并行请求数
enforceSizeThreshold: 50000, // 设置强制执行拆分的体积阈值为 50000B,同时会忽略其他限制(minRemainingSize,maxAsyncRequests,maxInitialRequests)
cacheGroups: {
defaultVendors: {
test: /[\/]node_modules[\/]/,
priority: -10, // 拆分的权重
reuseExistingChunk: true, // 如果当前 chunk 包含已从主 bundle 中拆分出的模块,则它将被重用,而不是生成新的模块
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true,
},
},
},
},
};
实践
实践过程中的拆包原则:
- 将变动的与不易变动的资源进行分离 ---> 有效利用缓存;
- 将 node_modules 中的资源拆分出来,如果 node_modules 中的资源不变,就可以有效利用缓存,避免受到业务代码频繁改动的影响;
- 将大的拆分成若干个小的 chunk ---> 缩短单个资源下载时间;
- 将公共模块抽离出来 ---> 避免资源被重复打包,这样也可以在一定程度上减小打包产物总体积;
- 将被多个 chunk 引用的包拆分成单独的模块;
这里给出实践的 optimization.splitChunks
配置:
module.exports = {
optimization: {
splitChunks: {
chunks: 'all',
cacheGroups: {
vendor: {
name: 'chunk-vendors',
test: /[\\/]node_modules[\\/]/,
priority: 10,
chunks: 'initial'
},
echarts: {
name: 'chunk-echarts',
priority: 20,
test: /[\\/]node_modules[\\/]_?echarts|zrender(.*)/
},
commons: {
name: 'chunk-commons',
minChunks: 3, // minimum common number
priority: 5,
reuseExistingChunk: true
},
lib: {
test(module) {
return (
module.size() > 160000 &&
/node_modules[/\\]/.test(module.nameForCondition() || '')
)
},
name(module) {
const packageNameArr = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/);
const packageName = packageNameArr ? packageNameArr[1] : '';
// npm package names are URL-safe, but some servers don't like @ symbols
return `chunk-lib.${packageName.replace("@", "")}`;
},
priority: 15,
minChunks: 1,
reuseExistingChunk: true,
},
}
},
}
}
配置说明:
- 先把大体积包拆分出来
- 先大体积包 echarts 拆分出来;
- 再把 node_modules 中体积大于 160000B 的依赖包拆出来(这里参考 next.js,将阈值设置为 160000B);
- 再考虑将 node_modules 中的剩余项打成一个 chunk;
- 将被引用次数大于等于 3 次的公共模块拆分出来;
注意优先级的配置
配置建议
- 可以先借助 webpack-bundle-analyzer 插件分析各模块的大小;
- 定位重复的模块;
- 参考优秀的开源项目;
- next.js
补充:个人觉得 optimization.splitChunks
没有绝对的最佳配置,只有最佳实践,要根据项目情况灵活配置~
参考
转载自:https://juejin.cn/post/7171079529757179917