Webpack splitChunks 分包策略详解与实战配置
本文深入解析 Webpack 中 splitChunks 插件的分包机制,涵盖拆包必要性、常见策略(如按经验、模块粒度、大小拆分)及默认配置详解。通过具体 cacheGroups 配置示例,展示如何优化代码加载性能、提升浏览器缓存命中率,并提供不同场景下的最佳实践建议。
一、为何实施代码分割
随着应用规模扩大,JavaScript 文件体积随之增加。大型 JS 文件会延长页面加载时间,损害用户体验。有效的分割策略可将大文件拆分为多个小块,将公共代码提取为独立 chunk,实现按需加载并充分利用浏览器缓存,合理配置可显著优化加载速度。
二、分割方案概述
入口起点(entry) 利用入口起点可将代码分离为多个独立文件,通过 webpack 配置数组结构的 entry 选项指定。此方式可分离 CSS 与 JavaScript 等不同类型文件,但存在无法动态加载、模块无法共享等局限。
代码分离(Code Splitting) 代码分离指将代码划分为不同包/块,支持按需加载,避免加载包含所有内容的单一包。用户仅需下载当前浏览页面所需的代码,可通过 ES6 模块的 import() 函数动态加载模块。动态导入的模块将被分割至独立 chunk。
打包分离(Bundle Splitting) webpack 为单一应用生成多个 bundle 文件。若仅修改巨大文件中的一行代码,用户仍需重新下载整个文件。若将其分为两个文件,用户仅需下载被修改的文件,另一文件可从缓存加载,从而减少重新发布及客户端重新下载的代码量。
综上,合理的分割策略可显著提升应用性能。代码分离通过按需加载减小初始下载量;打包分离将应用拆分为多个块以实现增量更新,减少不必要下载。依据具体场景选择合适方式可最大化优化加载性能。
三、splitChunks 机制解析
splitChunks 将符合拆分规则的构建内容抽离并单独打包,旨在提取公共模块,减少重复打包。splitChunks 的配置项用于确定具体拆分规则,其中 cacheGroups 配置项必须同时满足其下所有条件方可生效。
webpack5 中 splitChunks 的默认配置如下:
module.exports = {
optimization: {
splitChunks: {
chunks: 'async',
// 生成的 chunk 的最小体积,单位为字节(bytes)。内容超过了minSize的值,才会进行打包
minSize: 20000,
minRemainingSize: 0,
// 在拆分之前,必须共享的模块的最小 chunk 数。
minChunks: 1,
// 在按需加载时,允许的最大并行请求数。
maxAsyncRequests: 30,
// 入口点允许的最大并行请求数。
maxInitialRequests: 30,
// 超过这个值就会进行强制分包处理,无视minRemainingSize,maxAsyncRequests,maxInitialRequests
enforceSizeThreshold: 50000,
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10,
// 如果当前 chunk 包含已从主 bundle 中拆分出的模块,则它将被重用,而不是生成新的模块
reuseExistingChunk: true,
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true,
},
},
},
},
};其中 chunks 属性可配置值为 all、async、initial,默认值为 async。
- async:仅对异步加载进来的包校验分包规则并进行抽离。若动态加载的包同时引用其他包且命中分包规则,也会被抽离出来。
- initial:表示仅从入口模块进行拆分。
- all:表示入口模块和异步加载的模块均需进行拆分。
四、splitChunks 分割策略详解
split-by-experience:基于经验制定的分割策略,自动将常用 npm 包拆分为体积适中的 chunk,适用于大多数项目。如下示例,react、antd 会被拆分至单独 chunk,其余三方包归入 vendorjs。若需更细粒度拆分,仍需配置缓存组。
splitChunks: {
// chunks、minSize、minChunks 将对所有缓存组生效
chunks: 'all', // 对所有的chunk进行拆分
minSize: 20000, // 拆分 chunk 的最小体积 20000 bytes
minChunks: 2, // 需在两个模块中共享才进行拆分
cacheGroups: {
vendor: {
name: 'vendor', // chunk 的名称 vendor
test: /[\\/]node_modules[\\/]/i, // 匹配node_modules下所有的chunk
priority: 10, // 优先级10 优先将node_modules下的chunk拆分到vendor组
reuseExistingChunk: true, // 重用模块,而不是重新生成
enforce: true, // 强制拆分
},
default: { // 默认组 非node_modules下的文件块 将执行default缓存组规则
reuseExistingChunk: true,
priority: -10, // 优先级 -10
enforce: true, // 强制拆分
},
react: { // react组
name: 'react',
test: /[\\/]node_modules[\\/]react[\\/]/, // 匹配node_modules下的react库
priority: 20, // 优先级20 优先将node_modules下的react拆分出去
minChunks: 2,
reuseExistingChunk: true,
},
antd: { // antd组
name: 'antd',
test: /[\\/]node_modules[\\/]antd[\\/]/, // 匹配node_modules下的antd库
priority: 20, // 优先级20 优先将node_modules下的antd拆分出去
minChunks: 2,
reuseExistingChunk: true, // 重用模块,而不是重新生成
},
}
}split-by-module:按 NPM 包粒度拆分,每个 NPM 包对应一个 chunk。
若应用添加或升级某个 npm 包,vendor.js 的哈希值将改变,用户需重新下载 vendor.js。若对 antd 进行升级或新增/删除组件,用户无需重新下载 vendor.js,仅需下载 antd 模块对应的 chunk。因每个 chunk 拥有独立哈希值,修改单独 chunk 仅影响对应文件,不影响其他 chunk,从而实现 npm 包的增量更新。
若 npm 包数量较多,可能产生高并发请求。支持 http2 的浏览器无此问题,但不支持 http2 的 http1.1 浏览器可能存在队头阻塞。目前 http2 兼容性良好。
splitChunks: {
chunks: 'all',
enforceSizeThreshold: 50000,
cacheGroups: {
vendors: {
priority: -10,
test: /[\\/]node_modules[\\/]/,
name(module2) {
return module2.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)?.[1];
},
},
},
minSize: 0,
maxInitialRequests: Infinity,
},single-vendor:将所有 NPM 包代码打包至单一 chunk。
此情况下,只要三方包有改动,文件 hash 即改变。若频繁改动 npm 包,浏览器缓存效率相对较低。
vendor: {
name: 'vendor', // chunk 的名称 vendor
test: /[\\/]node_modules[\\/]/i, // 匹配node_modules下所有的chunk
priority: 10, // 优先级10 优先将node_modules下的chunk拆分到vendor组
reuseExistingChunk: true, // 重用模块,而不是重新生成
enforce: true, // 强制拆分
},split-by-size:根据模块大小自动进行拆分。
符合大小范围内的包将被拆分出来。
splitChunks: {
chunks: 'all',
minSize: 20000, // 20 KB
maxSize: 50000, // 50 KB
cacheGroups: {
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true,
},
},
},五、总结
需依据业务场景选择合适的分包策略,确定拆分力度与程度。需注意拆包后相同模块不应被重复打包。
至此,关于 webpack 中 splitChunks 分包策略的实现介绍完毕。更多相关 webpack splitChunks 分包策略内容请搜索本站历史文章或继续浏览下方相关文章,希望大家今后多多支持本站!
JS reduce实战:数组去重、扁平化与分组统计
2026-11-05 13:05:36
JS代码怎么在线压缩?新手操作指南与工具推荐
2026-11-04 18:07:25
fflate 与 pako.js 性能对比:JS 解压库怎么选
2026-11-03 22:54:05
JS DOM查询性能优化:缓存引用与减少重排重绘
2026-11-03 22:48:27
在线运行JavaScript代码时的沙箱限制与跨域问题
2026-11-03 22:29:33
