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

时间:2019-08-17 05:38:16

标签: webpack webpack-4

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

( 我试图指示此处讨论的babel loader [1],而不是去那里看-但这还不够,因为编译仍然会失败。 )

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

1 个答案:

答案 0 :(得分:3)

您似乎快到了。当您构建app1并只想使用node_modules中的app1时,可以将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的根,app1的根中的webpack配置)

使用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(例如,从react解析./node_modules

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

关于babel-loader的提示

  

((我曾尝试指示1这里讨论过的babel loader,但不要去那里看-但这还不够,因为编译仍然会失败。)

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

希望,会有所帮助。