Webpack 4 splitChunks 插件配置详解与实战避坑指南
本文深入解析 Webpack 4 中 splitChunks 插件的核心参数与配置策略。通过多个实战案例,详细演示如何利用 cacheGroups 进行模块复用、第三方库分离及动态引入处理。重点剖析生产模式下打包异常的原因,并提供手动配置缓存组以解决 vendor 合并问题的具体方案,帮助开发者掌握高效的代码分割技巧。
引言与初衷
初衷
Webpack 4 发布已有数月,观察发现包括作者在内,许多开发者对 splitChunks 插件的使用仍处于探索阶段。作者查阅了大量他人的配置示例,但大多未能完全满足需求或解决疑惑,相关 Issue 下也鲜有回复,因此决定通过实际测试进行记录与总结。若读者有更优方案,欢迎在评论区分享。
splitChunks 核心参数解析
常用参数
- minSize(默认值 30000):定义生成新代码块所需的最小体积阈值。
- minChunks(默认值 1):指定代码块在分割前被引用的最小次数。该参数旨在保证代码块的复用性,默认策略下即使仅被引用一次也可被分割。
- maxInitialRequests(默认值 3):限制一个入口点允许的最大并行请求数量。
- maxAsyncRequests(默认值 5):限制按需加载(异步加载)时的最大并行请求数量。
- chunks(默认值 async):可选值为 initial、async 和 all。
- test:用于筛选匹配该缓存组的模块。若不传递特定值,默认匹配所有模块。支持传入 RegExp、String 或 Function 类型。
- name:指定打包后 chunks 的名称,可接受字符串或根据条件自定义名称的函数。
- priority:定义缓存组打包的优先级顺序。
若对上述配置仍感陌生,建议查阅官方文档以获取更详尽的解释。
正文
基础配置与模块复用示例
首先总览所有配置项,随后将通过具体 Demo 演示常见需求的处理流程。
optimization: {
splitChunks: {
chunks: "async", // 必须三选一: "initial" | "all"(推荐) | "async" (默认就是async)
minSize: 30000, // 最小尺寸,30000
minChunks: 1, // 最小 chunk ,默认1
maxAsyncRequests: 5, // 最大异步请求数, 默认5
maxInitialRequests : 3, // 最大初始化请求书,默认3
automaticNameDelimiter: '~',// 打包分隔符
name: function(){}, // 打包后的名称,此选项可接收 function
cacheGroups:{ // 这里开始设置缓存的 chunks
priority: 0, // 缓存组优先级
vendor: { // key 为entry中定义的 入口名称
chunks: "initial", // 必须三选一: "initial" | "all" | "async"(默认就是async)
test: /react|lodash/, // 正则规则验证,如果符合就提取 chunk
name: "vendor", // 要缓存的 分隔出来的 chunk 名称
minSize: 30000,
minChunks: 1,
enforce: true,
maxAsyncRequests: 5, // 最大异步请求数, 默认1
maxInitialRequests : 3, // 最大初始化请求书,默认1
reuseExistingChunk: true // 可设置是否重用该chunk
}
}
}
},
接下来分析第一个示例。
entry: {
pageA: "./pageA", // 引用utility1.js utility2.js
pageB: "./pageB", // 引用utility2.js utility3.js
pageC: "./pageC" // 引用utility2.js utility3.js
},
optimization: {
splitChunks: {
cacheGroups: {
commons: {
chunks: "initial",
minChunks: 2,
maxInitialRequests: 5, // The default limit is too small to showcase the effect
minSize: 0 // This is example is too small to create commons chunks
}
}
}
},
结果如图所示,运行正常。文件 commons~pageA~pageB~pageC.js 对应 utility2.js,commons~pageB~pageC.js 对应 utility3.js。根据配置,utility2 被引用三次,因此首先被抽离至 commons~pageA~pageB~pageC.js;utility3 被引用两次,放入 commons~pageB~pageC.js;剩余仅被引用一次的 utility1.js 则直接归入 pageA.js。需注意,若 utility1.js 也被引用两次,它仍会新建一个 chunk 而非合并至 commons~pageB~pageC.js,除非它们属于同一入口才会合并。
mpageA.js pageB.js pageC.js

此处存在一个优化点:pageA.js、pageB.js 和 pageC.js 代码量虽少,但打包体积较大,这通常是由于 Webpack 运行时文件所致。可通过添加 runtimeChunk 配置来解决。
runtimeChunk: "single"
// 等价于
runtimeChunk: {
name: "manifest"
}
添加后效果改善。

第三方库分离与生产环境避坑
接着处理第三方模块引用:pageA 引入 vue.js,pageB 引入 react 和 react-dom。
vendor: {
test: /node_modules/,
chunks: "initial",
name: "vendor",
priority: 10,
enforce: true
}
然而,上述配置会导致 pageA、pageB 和 pageC 的所有库被打包至同一个 vendor.js 文件中。

若希望将 vendor.js 拆分为 pageA-vendor.js 和 pageB-vendor.js,经过多次尝试,发现最简单的方法是移除手动指定的 vendor 配置,交由插件自动处理。
splitChunks: {
chunks: "all",
cacheGroups: {
commons: {
chunks: "initial",
minChunks: 2,
maxInitialRequests: 5, // The default limit is too small to showcase the effect
minSize: 0 // This is example is too small to create commons chunks
}
}
},

随后将 webpack mode 改为 production 模式,发现相同配置下打包结果异常:vendor-pageB.js 被合并到了 pageB.js 内部。

经过长时间排查仍无法确定原因,最终采取手动配置方式,放弃部分自动化处理。
commons: {
chunks: "initial",
minChunks: 2,
maxInitialRequests: 5, // The default limit is too small to showcase the effect
minSize: 0 // This is example is too small to create commons chunks
},
'vendor-pageA': {
test: /vue/, // 直接使用 test 来做路径匹配
chunks: "initial",
name: "vendor-pageA",
enforce: true,
},
'vendor-pageB': {
test: /react/, // 直接使用 test 来做路径匹配
chunks: "initial",
name: "vendor-pageB",
enforce: true,
},
成功打包出预期结果。

动态引入与懒加载处理
动态引入
动态引入即常说的懒加载。在 pageA 和 pageB 中直接动态引入 common-async.js。此处推测 splitChunks 应能自动处理类似 commonChunk 中 async 或 child 类型的情况。
import(/* webpackChunkName: "common-async.js" */"./common-async").then(common => {
console.log(common);
})
结果良好,成功打包。

进一步测试:在 common-async.js 中引入共同代码 f.js,观察是否会出现重复打包。

f.js 成功被抽离,其他文件未重复打包,效果良好。

配置注意事项与建议
注意的地方
- cacheGroups 会继承并覆盖 splitChunks 的配置项,但 test、priority 和 reuseExistingChunk 仅能用于配置缓存组。
- 建议 cacheGroups 中的每一项都明确添加 chunks 参数,否则可能导致打包结果不符合预期。
- minSize 默认值为 30KB(注意这是压缩前的体积)。若模块小于 30KB,必须显式设置一个值,否则可能无法打包出预期结果,且该设置需置于 cacheGroups 内部。
- priority 在特定情况下非常有用,可用于设定打包 chunks 的优先级。
上述示例中配置了一个名为 commons 的组,其 name 属性可设置也可省略。作者未设置,建议读者尝试设置后的效果,从而理解在某些情况下不设置 name 更为合适。
commons: {
chunks: "initial",
minChunks: 2,
maxInitialRequests: 5, // The default limit is too small to showcase the effect
minSize: 0 ,
name: "commons"
},
源码
代码分割
代码懒加载
参考文章
webpack文档 官方demo
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。
JavaScript插件版本冲突怎么解决?npm安装报错排查
2026-11-03 23:58:39
怎么指定版本下载 pdf.js 旧版资源
2026-11-03 20:56:02
NW.js 应用打包指南:使用 nw-builder 生成多平台安装包
2026-11-03 20:07:02
JS控制台打印样式美化:使用%c自定义日志颜色
2026-11-02 10:29:52
Vue3 + Vite 项目创建与配置指南
2026-11-01 04:02:02








