【问题标题】:Webpack 4x how to exclude multiple node_modules directoriesWebpack 4x 如何排除多个 node_modules 目录
【发布时间】:2019-12-23 07:20:20
【问题描述】:

我有一个包含多个 node_modules 目录的项目

myproj
   |-->app1
     package.json
     |-->node_modules
     |-->src

   |-->origapp_reactnative
     package.json
     |-->node_modules
     |-->shared_src

   |-->app2
     package.json
     |-->node_modules
     |-->src

当使用 webpack 构建 app1 或 app2 时(从它们各自的根目录)。 我必须指定

   resolve.modules=[path.resolve(__dirname,"./node_modules")]

如果我不这样做,那么 webpack 将尝试从

中提取代码
   |-->origapp_reactnative
     |-->node_modules

因为 app1 或 app2 包含来自 shared_src 的源。 并且 webpack 尝试遵循 nodejs 约定并在 shared_src 旁边的目录中查找 node_modules。

这就是我将 resolve.modules 设置为绝对路径的原因。

但是,这会产生另一个我无法克服的问题: webpack 将绝对路径指定的 node_modules 中的依赖树展平。这就产生了依赖问题,不同版本的模块不能共存。

所以我正在寻找一种使用相对路径的方法

   resolve.modules=["./node_modules"]

但需要帮助弄清楚如何排除 node_modules

   |-->origapp_reactnative
     |-->node_modules

从 webpacks 考虑。

( 我曾尝试按照此处 [1] 的讨论指示 babel loader,不要看那里——但这还不够,因为编译仍然会失败。 )

[1]Webpack 2: How to exclude all node_modules except for

【问题讨论】:

    标签: webpack webpack-4


    【解决方案1】:

    你似乎快到了。当您构建 app1 并且只想使用来自 app1node_modules 时,您可以使用带有相对路径 app1/node_modulesresolve.modules

    解决方案resolve.modules

    app1 中的 webpack 配置:

    const path = require("path");
    ...
    
    module.exports = {
      ...
      resolve: {
        extensions: [".jsx", ".js"],
        modules: [path.basename(__dirname) + "/node_modules"]
      },
    };
    

    (假设:cwd 指向app1 的根,webpack 配置在app1 的根)

    使用path.basename,您可以使您的配置更加独立于实际项目名称,有效地使用设置modules: ["app1/node_modules"]。如果你从shared_src 导入一些东西,而他使用node_modules,它将通过节点解析遍历到myproj,并从那里找到路径app1/node_modules

    如果您仅在共享项目中安装了其他软件包,也可以将node_modules 添加为fallback

    // first entry takes precedence.
    modules: [path.basename(__dirname) + "/node_modules", "node_modules"]
    

    resolveLoader 可以设置为加载程序的额外属性,如果您之后碰巧遇到无法从node_modules 找到加载程序的错误。

    替代方案:resolve.alias

    如果您只需要从特定的 node_modules 文件夹中导入一些包, 你也可以使用resolve.alias(例如从./node_modules解析react):

    resolve: {
      alias: {
        react: path.resolve("./node_modules/react")
      }
    }
    

    关于 babel-loader 的注意事项

    (我已尝试按照此处1 的讨论指示 babel loader,不要看那里——但这还不够,因为编译仍然会失败。)

    Babel-loader 和 Co. 使用已经为 resolved 的绝对文件路径替换为 rule conditions,如果您想排除要转换的内容。在任何情况下,exclude 和加载器的其他过滤器选项都不会阻止您导入的模块(如node_modules 中的模块)被排除在外。当模块被过滤掉时,这仅意味着它们不会被 Babel 加载器(或您定义了规则条件的其他加载器)进一步处理。

    希望,这会有所帮助。

    【讨论】:

      猜你喜欢
      • 2016-01-05
      • 2018-10-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-03
      • 2021-11-22
      • 1970-01-01
      相关资源
      最近更新 更多