如何移除Webpack打包中的重复依赖代码?
我的本地NPM包依赖结构如下:
common-package ^ ^ | | father-package mother-package ^ ^ | | son-package
father-package和mother-package都引入了common-package,而son-package同时引入了这两个包。目前的问题是son-package的打包产物中common-package的代码重复,比如其中的User.ts类出现了两个定义。
我尝试通过调整webpack的optimization配置实现去重,但不确定具体操作。当前son-package的webpack.config.js配置如下:
const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { plugins:[ new HtmlWebpackPlugin({ template: './index.html', inject: true, filename: './index.html' }) ], optimization: { splitChunks: { cacheGroups: { commons: { test: /[\\/]node_modules[\\/]/, name: 'vendors', chunks: 'all', }, }, }, }, mode: 'development', devtool: 'source-map', target: 'es2017', entry: { index: './src/Index.ts' }, output: { path: `${path.resolve('dist')}`, filename: '[name].js', library: { type: 'module' }, chunkFormat: 'module' }, module: { rules: [ { test: /\.(ts|tsx)$/, use: 'ts-loader', exclude: /node_modules/ }, { test: /\.(js|jsx)$/, use: 'babel-loader', exclude: /node_modules/ }, ], }, resolve: { extensions: ['.js', '.ts'], } };
请问是否需要在father-package和mother-package的webpack.config.js中添加相同的optimization配置?
注:Node版本v18.11.0,NPM版本8.19.2,Webpack版本5。
不需要在father-package和mother-package中添加optimization配置,反而需要调整它们的打包策略,同时优化son-package的webpack配置来实现去重,具体步骤如下:
1. 让依赖包排除common-package的打包
在father-package和mother-package的webpack.config.js中添加externals配置,将common-package声明为外部依赖,这样它们的打包产物不会包含common-package的代码,只会保留引用:
module.exports = { // ...其他配置 externals: { 'common-package': 'common-package' } };
2. 调整son-package的splitChunks规则
当前你的splitChunks只匹配node_modules中的包,如果common-package是本地开发包(比如通过npm link引入),可能不在常规node_modules路径下,需要修改规则让webpack识别并提取它:
optimization: { splitChunks: { cacheGroups: { // 单独提取common-package commonPackage: { test: /common-package/, name: 'common', chunks: 'all', enforce: true // 强制提取,优先级高于其他规则 }, vendors: { test: /[\\/]node_modules[\\/]/, name: 'vendors', chunks: 'all', }, }, }, },
3. 确保webpack识别同一模块
如果common-package存在多路径引用(比如本地源码和node_modules中的副本),需要配置resolve.alias让所有引用指向同一个物理文件,避免webpack将其视为不同模块:
resolve: { alias: { 'common-package': path.resolve(__dirname, '../common-package') // 替换为你的common-package实际路径 }, extensions: ['.js', '.ts'], }
验证效果
完成上述配置后,重新打包son-package,搜索产物中的class User {应该只会出现一次,代码重复问题即可解决。
内容的提问来源于stack exchange,提问作者Elkin

