[webpack] 如果解决重复引用 node_modules 里面的不同版本的包(包重复问题)

解决重复引用 node_modules 中不同版本的包的问题,可以通过以下几种方式:

1.使用 npm 或者 yarn 的工具进行依赖的版本控制,尽量避免引用不同版本的同一个依赖库。在 package.json 文件中使用 "^"、"~"、">=" 等方式指定依赖版本,可以有效减少不同版本的包冲突问题。

2.使用 webpack 的 resolve.alias 配置选项,将需要共享的模块指定到一个目录下,然后在其它模块中使用别名引用该模块。例如,将需要共享的模块指定到 src/shared 目录下,然后在其它模块中使用别名 @shared 引用该模块,这样就可以保证在不同模块中引用相同的依赖库。
假设我们在项目中同时依赖了两个库:lodashlodash-es,并且它们分别被安装在了不同的目录下,如下所示:

Copy codenode_modules/
├── lodash/
└── lodash-es/

我们需要在项目中同时引用这两个库,但是如果我们在代码中分别使用 import _ from 'lodash'import _ from 'lodash-es',那么 webpack 会将它们打包成两个独立的模块,导致代码体积变大。

为了解决这个问题,我们可以通过 resolve.alias 配置项将它们指向同一个模块。具体做法是在 webpack 配置文件中添加以下内容:

module.exports = {
  // ...
  resolve: {
    alias: {
      'lodash-es': 'lodash'
    }
  }
}

这样一来,当我们在代码中使用 import _ from 'lodash-es' 时,webpack 会自动将它解析成对 lodash 的引用,从而避免了重复打包的问题。

3.使用 webpack 的 ProvidePlugin 插件,将需要共享的模块注入到全局作用域中,这样就可以在不同模块中共享相同的依赖库。例如,在 webpack 配置文件中添加以下代码:

const webpack = require('webpack');

module.exports = {
  // ...
  plugins: [
    new webpack.ProvidePlugin({
      $: 'jquery',
      jQuery: 'jquery',
      'window.jQuery': 'jquery',
    }),
  ],
};

这样在不同模块中就可以使用 $、jQuery、window.jQuery 全局变量引用 jquery 依赖库,避免了重复引用不同版本的 jquery 包的问题。

4.使用 webpack 的 resolve.modules 配置选项,将 node_modules 目录移动到项目根目录之外,然后在 resolve.modules 中添加该目录的绝对路径,这样就可以解决不同模块中引用相同依赖库不同版本的问题。例如,在 webpack 配置文件中添加以下代码:

const path = require('path');

module.exports = {
  // ...
  resolve: {
    modules: [
      path.resolve(__dirname, 'src'),
      'node_modules',
    ],
  },
};

这样 webpack 在查找依赖库的时候,会先在项目根目录下的 src 目录中查找,如果没有找到再去 node_modules 目录中查找,避免了不同模块中引用相同依赖库不同版本的问题。