You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

单个webpack打包产物存在重复依赖但package-lock.json无多版本记录

webpack-bundle-analyzer输出图

问题确认

你观察到的属于单打包产物下的依赖重复打包问题,哪怕package-lock.json中只有唯一版本记录也可能出现,不代表一定存在多版本依赖。

重复成因&结构差异说明

这种同版本重复打包、且结构不一致的情况,90%以上是同一个包被走了不同的模块入口导致的:
现在绝大多数第三方NPM包都会同时提供ESM(ES模块)和CJS(CommonJS)两种格式的产物,分别对应package.json中的module和main字段。如果你的业务代码、或者你依赖的其他第三方包,分别通过不同的规范引入了apollo、sentry,webpack会将两种格式的产物判定为不同的模块,分别打包进产物,自然结构会有明显差异。
除此之外还有两种少见的触发原因:

  • webpack的resolve.modules配置优先级异常,导致同一个包从项目根目录node_modules、子依赖包下的node_modules两个路径被分别加载,哪怕版本完全一致也会被分开打包
  • 配置的模块别名存在冲突,导致同一个包被匹配到了不同的解析路径

修复方案

  • 首先排查模块引入路径:执行打包命令时添加--json > stats.json参数导出打包统计文件,搜索apollo、sentry对应的模块路径,确认是否存在两个不同的入口文件(比如一个是xxx.cjs.js,一个是xxx.esm.js)
  • 固定依赖入口:如果是入口不一致导致的,在webpack配置的resolve.alias中为两个包指定统一的入口即可,示例配置如下:
const path = require('path')
module.exports = {
  resolve: {
    alias: {
      '@apollo/client': path.resolve(__dirname, 'node_modules/@apollo/client/index.esm.js'),
      '@sentry/browser': path.resolve(__dirname, 'node_modules/@sentry/browser/index.esm.js')
    }
  }
}
  • 优化公共依赖提取规则:检查webpack的splitChunks配置,确保所有node_modules下的依赖都会被提取到公共chunk,避免重复打包:
module.exports = {
  optimization: {
    splitChunks: {
      chunks: 'all',
      cacheGroups: {
        vendors: {
          test: /[\\/]node_modules[\\/]/,
          name: 'vendors',
          priority: -10
        }
      }
    }
  }
}
  • 调整模块解析优先级:在resolve.modules中配置优先读取根目录的node_modules,避免路径解析异常:
module.exports = {
  resolve: {
    modules: [path.resolve(__dirname, 'node_modules'), 'node_modules']
  }
}

内容的提问来源于stack exchange,提问作者Rob Allsopp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 14:48:03