Webpack官方文档这么说:代码分离是webpack中最引人注目的特性之一。此特性能够把代码分离到不同的bundle中,然后可以按需加载或并行加载这些文件。代码分离可以用于获取更小的bundle,以及控制资源加载优先级,如果使用合理,会极大影响加载时间。
要想做chunk分离优化,首先要知道当前哪些chunk包体积较大,才能明确方向。以vue-cli3.0为例,开始Webpack打包分离chunk优化之旅。
vue-cli3默认配置build,打包结果如下:

Webpack4.0升级以后,CommonsChunkPlugin被删除,被optimization.splitChunks和optimization.runtimeChunk配置化所代替。
Webpack自动分离chunk包基于以下几个条件:
- 来自公共模块node_modules
- 压缩前包体积大于30kb(默认)
- 按需加载并行请求chunk包数量不超过5个(默认)
- 首屏初始化加载并行请求chunk包数量不超过3个(默认)
SplitChunksPlugin默认配置:
optimization: {
minimize: false,
splitChunks: {
chunks: 'all',//表示显示块的范围,有三个可选值:initial(初始块)、async(按需加载块)、all(全部块)(default=all);
name: true,//拆分出来块的名字(Chunk Names),默认由块名和hash值自动生成;
minChunks: 1,//在分割之前模块的被引用次数(default=1)
minSize: 30000,//代码块的最小尺寸(default=30000)
maxAsyncRequests: 5,//按需加载最大并行请求数量(default=5)
maxInitialRequests: 3,//一个入口的最大并行请求数量(default=3)
automaticNameDelimiter: '~',
cacheGroups: {//可以继承/覆盖上面 splitChunks 中所有的参数值
vendors: {
name: "vendors",
chunks: "all",
test: /node_modules\//,//表示要过滤 modules,默认为所有的 modules,可匹配模块路径或 chunk 名字,当匹配的是 chunk 名字的时候,其里面的所有 modules 都会选中;
priority: 10,//表示抽取权重,数字越大表示优先级越高。因为一个 module 可能会满足多个 cacheGroups 的条件,那么抽取到哪个就由权重最高的说了算;
reuseExistingChunk: true//表示是否使用已有的 chunk,如果为 true 则表示如果当前的 chunk 包含的模块已经被抽取出去了,那么将不会重新生成新的。
},
commons: {
name: "commons",
chunks: "initial",
minChunks: 2
}
}
},
runtimeChunk: {
name: "manifest"
}
}
但是,默认配置build结束,公共vendor包体积明显太大,影响加载性能。尽量控制每个chunk包体积不大于30kb。

下面工作就是就是继续分离vendors包。
优化后的配置:
optimization: {
splitChunks: {
chunks: "all",
minSize: 30000,
maxAsyncRequests: 5,
maxInitialRequests: 5,
cacheGroups: {
vue: {
test: /[\\/]node_modules[\\/](vue)[\\/]/,
name: "vue",
priority: 2
},
router: {
test: /[\\/]node_modules[\\/](vue-router)[\\/]/,
name: "vue-router",
priority: 2
},
vendors: {
test: /[\\/]node_modules[\\/]/,
name: "vendors",
priority: 1,
reuseExistingChunk: true
}
}
},
runtimeChunk: {
name: "manifest"
}
}
项目重新build,结果如下:

总结:本次只是对splitChunks优化分chunk打包策略的实践,大家具体如何制定策略还得根据实际业务来。