Webpack 4x 如何排除多个 node_modules 目录

Webpack 4x how to exclude multiple node_modules directories

我有一个包含多个 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

出于对 webpack 的考虑。

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

[1]

你似乎快到了。当您构建 app1 并且只想使用 app1 中的 node_modules 时,您可以使用 resolve.modules 和相对路径 app1/node_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 可以设置为 loader 的额外 属性,如果你之后碰巧遇到无法从 node_modules 中找到 loader 的错误。

选择:resolve.alias

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

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

关于 babel-loader 的注意事项

( I have tried to instruct babel loader as discussed here 1, not to look there -- but that's not enough, because compilation still will fails. )

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

希望对您有所帮助。