导读:本期聚焦于猫儿创作的《Webpack 中 optimization.mergeDuplicateChunks 是如何合并重复 Chunk 的?》,敬请观看详情。Webpack 的 optimization.mergeDuplicateChunks 选项虽然默认开启,但它的内部行为并不像名字那样直观。该配置的核心作用是在 chunk 生成之后、输出之前,检查所有 chunk 之间的模块依赖关系,把被多个 chunk 同时包含的相同模块提取到一个可共享的 chunk 中,从而消除重复代码。和 splitChunks 不同,mergeDuplicateChunks 更像是一个自动清理步骤,专门针对动态导入、多入口配置或 splitChunks 未覆盖到的场景。本文通过配置示例和构建产物对比,展示如何验证该选项是否真正生效,分析它与 splitChunks、runtimeChunk 的协作关系,并指出在实际项目中关闭它可能带来的风险或收益。理解这一机制,有助于更精准地控制 Webpack 的输出结构,避免构建体积出现难以排查的膨胀。

在 Webpack 的打包结果中,经常会出现同一个模块被复制到多个 chunk 里的情况。比如两个入口文件都引入了同一个工具函数,或者多个动态导入的模块共享了某个依赖,如果处理不当,浏览器就可能重复下载相同的代码。optimization.mergeDuplicateChunks 正是 Webpack 内部用来解决这类重复问题的配置项。它会在 chunk 生成之后、最终资产输出之前,分析模块与 chunk 之间的关联,将那些被多个 chunk 同时包含的模块合并到一个可共享的 chunk 中。理解这个选项的工作机制,有助于我们更好地设计代码分割策略,避免构建产物出现难以排查的体积膨胀。

Webpack 中 optimization.mergeDuplicateChunks 是如何合并重复 Chunk 的?

mergeDuplicateChunks 的作用机制与默认行为

Webpack 在完成模块编译和依赖解析后,会进入 seal 阶段,在这个阶段里它会根据入口配置和动态导入生成一个个 chunk。默认情况下,每个入口会对应一个初始 chunk,而动态导入的模块则会形成独立的异步 chunk。如果同一个模块被多个 chunk 引用,Webpack 并不会自动把它们合并,除非有相应的优化逻辑介入。

optimization.mergeDuplicateChunks 就是其中的一个优化项,它的默认值是 true。它的工作方式可以简单理解为:在 chunk 图构建完成后,遍历所有 chunk,找出那些被多个 chunk 包含的相同模块,然后把这些模块从原 chunk 中移除,并放入一个新的共享 chunk 中。这个共享 chunk 会被所有引用它的 chunk 通过 chunk 关系连接起来。这样做不仅能减少重复代码,还能让浏览器在首次加载时多请求一个文件,但总体下载体积会下降。

值得注意的是,mergeDuplicateChunks 与 splitChunks 是两个独立的机制。splitChunks 是根据开发者配置的规则主动提取公共模块,用来生成独立的缓存组;而 mergeDuplicateChunks 则是在 splitChunks 执行之后仍然存在重复模块时,进行的自动清理。即使你在配置中把 splitChunks 设置为 false,mergeDuplicateChunks 依然会生效。下面的配置示例演示了这种独立性:

// webpack.config.js
module.exports = {
  entry: {
    pageA: './src/pageA.js',
    pageB: './src/pageB.js'
  },
  output: {
    filename: '[name].bundle.js'
  },
  optimization: {
    mergeDuplicateChunks: true,
    splitChunks: false
  }
};

在这个例子中,如果 pageA.js 和 pageB.js 都引入了同一个模块 utils.js,那么开启 mergeDuplicateChunks 后,Webpack 会生成一个额外的共享 chunk,而 pageA.bundle.js 和 pageB.bundle.js 中的 utils 代码会被移除。如果将该选项设为 false,则 utils 代码会分别出现在两个 bundle 中,造成重复。

如何验证 mergeDuplicateChunks 的合并效果

要确认 mergeDuplicateChunks 是否真正对构建产物产生了影响,最直接的方法是比较开启和关闭该选项时的输出文件。可以准备一个最小项目,包含两个入口文件,并且两个入口都导入同一个模块。先设置 mergeDuplicateChunks: false 执行一次构建,观察 dist 目录下的文件数量和各文件内容;再改为 true 重新构建,对比产物变化。

例如,在关闭该选项时,dist 目录可能只包含 pageA.bundle.js 和 pageB.bundle.js 两个文件,而 utils 的代码被完整地复制到了这两个文件中。开启之后,dist 目录中会多出一个类似 pageA~pageB.bundle.js 的文件,也就是 Webpack 自动生成的共享 chunk。原来的两个 bundle 文件体积会明显变小,而新增的共享 chunk 则包含了 utils 模块的代码。

除了人工观察文件,还可以通过 Webpack 的 stats 数据来做更精确的分析。在构建命令中加入 --json > stats.json,然后解析 stats.json 中的 chunks 和 modules 字段,就能看到每个 chunk 包含了哪些模块,以及模块在哪些 chunk 中重复出现。下面的命令行示例可以生成 stats 文件:

npx webpack --config webpack.config.js --json > stats.json

在 stats.json 中,可以搜索模块 id 或者模块路径,查看它出现在哪些 chunks 数组里。如果同一个模块出现在两个以上的 chunk 中,说明 mergeDuplicateChunks 没有生效或者该模块被排除在合并范围之外。这种方式适合在大型项目中排查重复模块的来源。

mergeDuplicateChunks 与 splitChunks、runtimeChunk 的协作关系

很多情况下,开发者已经配置了 splitChunks 来提取公共依赖。splitChunks 会根据 cacheGroups 中的规则,把满足条件的模块打包到独立的 chunk 中,并生成一个稳定的缓存组名称。如果 splitChunks 已经覆盖了所有公共模块,那么 mergeDuplicateChunks 能够处理的重复模块就会减少,但它仍然可能在其他地方发挥作用。例如动态导入的模块之间共享的依赖,如果这些依赖没有被 splitChunks 的 cacheGroups 规则匹配到,mergeDuplicateChunks 就可以负责清理这些重复。

runtimeChunk 的关系也值得注意。runtimeChunk 主要负责将 Webpack 的运行时代码提取到单独的文件中,它本身不会影响 mergeDuplicateChunks 的合并逻辑。但如果运行时被单独提取后,多个 chunk 对运行时的引用就不会造成重复,这反而减少了 mergeDuplicateChunks 需要处理的对象。因此在实际项目中,同时开启 splitChunks、runtimeChunk 和 mergeDuplicateChunks 通常能获得更干净的输出结构。

不过也需要认识到,mergeDuplicateChunks 生成的共享 chunk 名称是自动生成的,可能包含波浪线或数字,这会对长期缓存和文件指纹造成一定影响。如果项目对 chunk 命名有严格要求,可以通过 splitChunks.nameoutput.chunkFilename 进行统一管理。另外,在微前端或模块联邦场景下,有时希望某个模块在多个子应用中保持独立,避免共享 chunk 加载失败导致整体不可用,这时可以考虑关闭 mergeDuplicateChunks,让每个子应用都带有完整的模块代码。

常见误区与实战建议

一个常见的误区是把 mergeDuplicateChunks 等同于代码分割。实际上,它的目标是去重,而不是创建按需加载的边界。它不会分析模块的异步加载时机,也不会根据缓存策略生成更细粒度的拆分。如果想要实现真正的按需加载和缓存复用,仍然需要依赖 splitChunks 的 cacheGroups 或动态导入语法。

另一个误区是认为关闭 mergeDuplicateChunks 就能减少 HTTP 请求数量。确实,关闭该选项后不会生成额外的共享 chunk,所以初始请求的文件数量可能变少,但代价是每个 chunk 都包含了重复的模块代码,整体传输体积会上升。对于网络带宽受限的用户来说,这反而可能降低加载性能。因此除非有明确的架构需求,否则建议保留默认开启状态。

在排查构建体积问题时,可以结合 Webpack Bundle Analyzer 等工具可视化 chunk 之间的模块分布。如果发现同一个模块出现在多个 chunk 中,先检查 splitChunks 的配置是否合理,再确认 mergeDuplicateChunks 是否被意外关闭。下面是一个简单的对比表格,展示不同配置组合下的典型结果:

配置组合输出结果适用场景
splitChunks: false, mergeDuplicateChunks: true自动生成共享 chunk,重复模块只出现一次不想手动配置 splitChunks,但希望自动去重
splitChunks: true, mergeDuplicateChunks: truesplitChunks 先提取公共模块,mergeDuplicateChunks 清理剩余重复大多数常规项目,推荐组合
splitChunks: false, mergeDuplicateChunks: false重复模块被复制到所有引用它的 chunk 中微前端隔离、特殊缓存需求

总之,optimization.mergeDuplicateChunks 是 Webpack 内部一个轻量但有效的去重工具。理解它的触发时机和与 splitChunks 的配合方式,可以帮助我们在面对复杂的构建产物时做出更合理的优化决策。日常开发中保持默认开启,遇到特定隔离需求时再有针对性地关闭,是较为稳妥的做法。

WebpackmergeDuplicateChunks重复Chunk修改时间:2026-08-20 20:33:26

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。