Webpack无法排除node_modules文件夹

114
我正在构建一个Node框架,使用webpack(虽然我应该承认应该使用gulp)。当我包含EJS模块时,webpack会将其包含在编译后的源代码中,尽管我明确告诉它要排除node_modules目录。
module.exports = {
    context: __dirname,
    target: 'node',
    // ...
    output: {
        libraryTarget: 'commonjs'
        // ...
    },
    module: {
        loaders: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                loader: 'babel-loader?{ "stage": 0, "optional": ["runtime"] }'
            }
        ]
    }
};

你可以看到,我有一个用于JS文件的测试,并告诉它排除node_modules;为什么它会忽略我的排除?


干得好,朋友。谢谢你。 - Justin Meskan
6个回答

239

根据你的配置文件,看起来你只是在使用 babel-loader 解析时排除了 node_modules,但并没有将其排除在打包过程之外。

为了排除 node_modules 和原生的Node.js库(native node libraries)不被打包,你需要:

  1. 在你的 webpack.config.js 中添加 target: 'node'。这会将 Node.js 定义为捆绑包运行的环境。对于 webpack,它会在打包过程中改变块加载行为、可用的外部模块和生成的代码风格(例如使用 require() 来替代 ES6 的 import/export)。

  2. nodeexternalPresets 设置为 true。在 Webpack@5 中,这个配置将排除原生的Node.js模块(例如 path、fs 等)不被打包。

  3. 使用 webpack-node-externals 以排除其他的 node_modules

因此,你的最终配置文件应该如下所示:

var nodeExternals = require('webpack-node-externals');
...
module.exports = {
    ...
    target: 'node', // use require() & use NodeJs CommonJS style
    externals: [nodeExternals()], // in order to ignore all modules in node_modules folder
    externalsPresets: {
        node: true // in order to ignore built-in modules like path, fs, etc. 
    },
    ...
};

18
在浏览器上有类似的东西吗?(即目标:'browser') - Andrea.cabral
我正在尝试理解 exclude: /node_modules/ 的作用。你能详细说明一下吗?如果我们不加这个会发生什么? - Šime Vidas
这是一个正则表达式。如果你不包含它,node_modules将被包含进去。 - meredrica
了不起的回答和能力。 - Geek Stocks
5
@ŠimeVidas 这将从 node_modules 目录中排除 babel-loader 的运行,但不会将其从捆绑包中排除。 - mlg87
显示剩余3条评论

24

如果你在使用TypeScript时遇到了这个问题,可能需要在您的tsconfig.json文件中添加skipLibCheck: true


1
你,我的朋友,是一个救命恩人。 - Jim Doyle

11

尝试使用绝对路径:

exclude:path.resolve(__dirname, "node_modules")

你能展示一下这个项目的结构吗?文件结构。 - Alan
4
为什么这样做?/node_modules/不会匹配节点模块中的任何可能路径吗? - Jamie Marshall

0

由于某些原因,以上的解决方案在我的TypeScript项目中并没有起作用,经过试验,我发现配置生产和开发模式的webpack选项是可行的。

步骤1

安装webpack-merge(这将允许你拥有类似的配置

npm install --save-dev webpack-merge

步骤二。

在与您的webpack.config.js相同的目录中创建webpack.dev.jswebpack.prod.js文件。

touch webpack.dev.js webpack.prod.js

第三步。

将此代码粘贴到您的webpack.dev.js文件中:

// webpack.dev.js
const { merge } = require("webpack-merge");
const config = require("./webpack.config.js");

module.exports = merge(config, {
  mode: "development",
  devtool: "inline-source-map",
});
  • 将相同的代码粘贴到webpack.prod.js文件中,但将mode更改为'production'并删除devtool键。
// webpack.prod.js
const { merge } = require("webpack-merge");
const config = require("./webpack.config.js");

module.exports = merge(config, {
  mode: "production",
});

步骤 4。

更新您的 package.json 文件以使用新的配置文件:

// package.json
"scripts": {
    "dev": "webpack --watch --config webpack.dev.js",
    "build": "webpack --watch --config webpack.prod.js"
  },

现在只需执行npm run dev即可查看您的更改。

使用此解决方案,您无需为每个更改运行构建,并且编译器会排除node_modules

您可以阅读更多关于此解决方案的信息webpack生产模式


-4
这对我有用:
排除:[/bower_components/, /node_modules/]

module.loaders

自动应用的加载器数组。

每个项目可以具有以下属性:

test:必须满足的条件

exclude:不能满足的条件

include:必须满足的条件

loader:由“!”分隔的加载器字符串

loaders:作为字符串的加载器数组

条件可以是RegExp、绝对路径开头或这些之一的数组,结合“and”使用。

请参见http://webpack.github.io/docs/configuration.html#module-loaders


-7

尝试下面的解决方案:

exclude:path.resolve(__dirname, "node_modules")

15
欢迎来到StackOverflow。如果您在其他答案的基础上提供了额外的价值,那就更好了。但在这种情况下,您的回答并没有提供额外的价值,因为另一位(Alan)用户已经在5年前发布了该解决方案。如果您获得足够的声誉,请投票支持它。 - Oleg Valter is with Ukraine

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接