打包出来的文件,第三方依赖库打包成一个js太大了,导致首屏加载比较慢。想要做到的是抽离出几个比较大的依赖,单独作为包。这样之后,首屏加载就可以并行下载这些依赖。
下面这个配置对象代表 SplitChunksPlugin 的默认行为。
module.exports = {
//...
optimization: {
splitChunks: {
chunks: 'async',//三选一:"initial" 初始化,"all"(默认就是all),"async"(动态加载)
minSize: 20000,//当导入的模块最小是多少字节才会进行代码分割
minRemainingSize: 0,//解析见代码下面的文字说明,不用设置
minChunks: 1,//当一个模块被导入(引用)至少多少次才对该模块进行代码分割
maxAsyncRequests: 30,//按需加载时的最大并行请求数
maxInitialRequests: 30,//入口点的最大并行请求数
enforceSizeThreshold: 50000,//解析见代码下面的文字说明,不用设置
cacheGroups: {//缓存组,这里是我们表演的舞台,抽取公共模块什么的,都在这个地方
defaultVendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10,//优先级
reuseExistingChunk: true,
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true,
},
},
},
},
};
chunks: ‘async’,//三选一:“initial” 初始化,“all”,“async”(动态加载)
initial:,会将入口文件中的依赖包重新切割为一个新的文件,其它文件中动态引入的不会进行拆分。(例如入口文件router的引入import store from '@/store/index.js';)
async:和initial相反,它只会将中动态引入的文件进行拆分。(例如路由文件的动态加载)
all:包含前两个,同步引入的和import动态引入的模块都会进行拆分。
通过 cacheGroups,可以自定义 chunk 输出分组。设置 test 对模块进行过滤,符合条件的模块分配到相同的组。splitChunks 默认情况下有如下分组:
module.exports = {
// ...
optimization: {
splitChunks: {
// ...
cacheGroups: {
defaultVendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10,
reuseExistingChunk: true,
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true,
},
},
},
},
};
意思就是存在两个默认的自定义分组,defaultVendors 和 default,defaultVendors 是将 node_modules 下面的模块分离到这个组。
可以看到打包出来的文件:

module.exports = {
// ...
optimization: {
splitChunks: {
// ...
cacheGroups: {
common: {
//src下同步引入的模块,全部放到common.js中
name: "common",
test: /[\\/]src[\\/]/,
minSize: 1024,
chunks: "initial",
priority: 5
},
defaultVendors: {
//第三方依赖库,全部放到venders.js中
test: /[\\/]node_modules[\\/]/,
priority: -10, // 优先级
name: 'vendors',
chunks: 'all',
reuseExistingChunk: true, // 如果一个模块已经被打包过了,那么这个模块也不会被打包
},
default: {//分包的基本配置
minChunks: 2, // 被超过两个模块引用,才会被打包(可以去掉)
priority: -20, // 优先级
reuseExistingChunk: true, // 如果一个模块已经被打包过了,那么这个模块也不会被打包
},
},
},
},
};
增加一个common缓存组的配置,值得注意的是它的chunks我设置了: “initial”,因为动态引入的js文件,已经默认导出单独的chunk了,这里我只是想把入口文件中的同步引入的文件导出为单独的chunk,而异步动态引入的还是和之前一样即可,这样打包出来如下图,入口文件app.js就少了很多东西,都跑到common.js中去了:

另外,需要注意地是priority优先级,越大则越先处理。
接下来,我看到我项目中,有几个依赖占比特别大,我也想把它单独拆出来,就可以类似地创建几个缓存组:
splitChunks: {
chunks: 'all', // 同步或异步引入的代码,都参与代码分割
minSize: 10000, // 设置最小分割大小,小于10k的文件不分割
cacheGroups: {
vue3QrReader: {
name: "vue3-qr-reader",
priority: 7,
test: /[\\/]node_modules[\\/]_?vue3-qr-reader(.*)/,
chunks: "all",
minSize:0,
},
vconsole: {
name: "vconsole",
priority: 7,
test: /[\\/]node_modules[\\/]_?vconsole(.*)/,
chunks: "all",
minSize:0,
},
vant: {
name: "vant",
priority: 6,
test: /[\\/]node_modules[\\/]_?vant(.*)/,
chunks: "all",
minSize:0,
},
common: {
//src下同步引入的模块,全部放到common.js中
name: "common",
test: /[\\/]src[\\/]/,
minSize: 1024,
chunks: "initial",
priority: 5
},
defaultVendors: {
//第三方依赖库,全部放到venders.js中
test: /[\\/]node_modules[\\/]/,
priority: -10, // 优先级
name: 'vendors',
chunks: 'initial',
reuseExistingChunk: true, // 如果一个模块已经被打包过了,那么这个模块也不会被打包
},
default: {//分包的基本配置
minChunks: 2, // 被超过两个模块引用,才会被打包(可以去掉)
priority: -20, // 优先级
reuseExistingChunk: true, // 如果一个模块已经被打包过了,那么这个模块也不会被打包
},
},
}
实现效果:
