cachegroups是splitchunks的实际执行引擎,决定模块归属、通过test/priority/reuseexistingchunk控制分包逻辑,并需配合contenthash和runtime提取实现长缓存。

核心在于用好 cacheGroups —— 它不是辅助项,而是 splitChunks 的实际执行引擎。所有分包逻辑都由它驱动,而长缓存效果则依赖于稳定、可预测的 chunk 名称和内容哈希。
明确 cacheGroups 的作用机制
cacheGroups 决定“哪个模块进哪个包”,它通过 test 匹配模块路径、priority 解决规则冲突、reuseExistingChunk 避免重复打包。上层配置(如 minSize、chunks)会默认继承给每个 cacheGroup,但只有 test/priority/reuseExistingChunk 是 cacheGroup 独有的。
- 一个 module 可能同时匹配多个 cacheGroup,最终归属由 priority 数值大的决定
- priority 为正数更优(比如 20 > -10),官方默认 vendors 是 -10,default 是 -20
- reuseExistingChunk: true 表示如果某模块已被前序 cacheGroup 提取过,后续组就跳过,不重复打包
按依赖类型分层定义 cacheGroups
把第三方库、内部公共库、业务通用模块逐层隔离,既利于复用,也便于单独设置缓存策略。
- 第三方稳定库:匹配 node_modules 中特定包,设高 priority,name 固定(如 'vendors'),启用 enforce: true 强制提取
- 公司级 UI 组件库:用正则匹配 @bytedesign、@ant-design 等 scope,独立命名(如 'ui-lib'),避免和普通 node_modules 混在一起
- 业务基础模块:例如 utils、hooks、apis,可通过 context 路径匹配 src/common/ 或 src/lib/,设中等 priority
- 兜底公共模块:default 组保留 minChunks: 2 + reuseExistingChunk: true,只收那些被多个 entry 共用、又没被前面规则捕获的模块
示例片段:
cacheGroups: {vendors: { test: /[\/]node_modules[\/](react|react-dom|lodash)[\/]/, name: 'vendors', priority: 30, chunks: 'all', enforce: true },
uiLib: { test: /[\/]node_modules[\/](@ant-design|@bytedesign)[\/]/, name: 'ui-lib', priority: 25, chunks: 'all' },
common: { test: /[\/]src[\/](common|lib)[\/]/, name: 'common', priority: 15, minChunks: 2 },
default: { priority: 1, minChunks: 2, reuseExistingChunk: true }
}
配合 output 和 optimization 实现长缓存
仅靠分包不够,要让浏览器长期复用,必须保证文件名和内容哈希稳定。
- 关闭 name: true(默认),改用 name: '[name].[contenthash:8]',确保内容不变时 hash 不变
- 设置 automaticNameDelimiter: '-',避免 ~ 在某些 CDN 或 Nginx 规则里引发解析问题
- 将 runtime 提取为独立 chunk:runtimeChunk: { name: 'runtime' },防止 vendor 变动导致 runtime hash 改变,连带污染所有 chunk
- 对 vendors 和 ui-lib 这类极少更新的包,可加 filename: '[name].[contenthash:12].js',延长 CDN 缓存周期
验证与调优关键点
配置完别急着上线,用几个简单方式确认是否生效:
- 运行 webpack --stats-chunk-modules > stats.json,用 Webpack Analyse 可视化查看每个 chunk 包含哪些 module
- 检查 dist 目录输出的文件名是否含 contenthash,且相同依赖是否始终归入同一文件(如 antd 总在 ui-lib.js)
- 修改一个业务文件,观察 vendors.js 和 runtime.js 的 hash 是否不变;修改 lodash 版本,只 vendors.js hash 变,其他不动
- 若发现某模块没进预期 chunk,用 stats 查看它的 issuer 和 chunks,反推是 test 没匹配上,还是 priority 被更高组抢走











