113

I'm using webpack for a Node framework that I'm building (though I should probably use gulp, admittedly). When I include the EJS module, webpack includes it in the compiled source, even though I explicitly tell it to exclude the node_modules dir.

module.exports = {
    context: __dirname,
    target: 'node',
    // ...
    output: {
        libraryTarget: 'commonjs'
        // ...
    },
    module: {
        loaders: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                loader: 'babel-loader?{ "stage": 0, "optional": ["runtime"] }'
            }
        ]
    }
};

As you can see, I have a test for JS files, and I tell it to exclude node_modules; why is it ignoring my exclude?

ndugger
  • 7,373
  • 5
  • 31
  • 42

6 Answers6

236

From your config file, it seems like you're only excluding node_modules from being parsed with babel-loader, but not from being bundled.

In order to exclude node_modules and native node libraries from bundling, you need to:

  1. Add target: 'node' to your webpack.config.js. This will define NodeJs as the environment in which the bundle should run. For webpack, it changes the chunk loading behavior, available external modules and generated code style (ie. uses require() for NodeJs) it uses during bundling.

  2. Set the externalPresets of node to true. As of Webpack@5, This configuration will exclude native node modules (path, fs, etc.) from being bundled.

  3. Use webpack-node-externals in order to exclude other node_modules.

So your result config file should look like:

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. 
    },
    ...
};
codejedi365
  • 1,074
  • 9
  • 13
lyosef
  • 6,092
  • 2
  • 27
  • 20
  • 18
    Is there something similar on the browser? (i.e. target: 'browser') – Andrea.cabral Oct 25 '16 at 04:57
  • I’m trying to understand what `exclude: /node_modules/` does. Could you elaborate? What could happen if we would leave it out? – Šime Vidas Jan 08 '17 at 22:41
  • It's a regex. if you leave it out, node_modules will be included – meredrica Jul 17 '17 at 07:34
  • 5
    @ŠimeVidas it will exclude the `node_modules` dir from having the `babel-loader` run over it, but it will not exclude it from the bundle – mlg87 Jul 24 '18 at 17:34
  • I implemented this but got error that 'Uncaught ReferenceError: require is not defined'. – Ali Feb 25 '23 at 23:12
  • In other for this solution to work, don't forget to install the [webpack-node-externals](https://www.npmjs.com/package/webpack-node-externals) library. `npm install webpack-node-externals --save-dev` @Ali – Victor Eke May 06 '23 at 15:56
  • In my case " target:"node", was missing in the config section. Thanks for help :) – Rakesh Chouhan May 27 '23 at 17:09
25

If you ran into this issue when using TypeScript, you may need to add skipLibCheck: true in your tsconfig.json file.

mattnedrich
  • 7,577
  • 9
  • 39
  • 45
11

Try use absolute path:

exclude:path.resolve(__dirname, "node_modules")
Alan
  • 596
  • 5
  • 18
0

For some reason, the solutions above didn't work for me in my TypeScript project, what worked was configuring webpack production and development mode options.

Step 1

Install webpack merge (This allows you to have a similar configuration)

npm install --save-dev webpack-merge

Step 2.

Create webpack.dev.js and webpack.prod.js files in the same directory as your webpack.config.js.

touch webpack.dev.js webpack.prod.js

Step 3.

Paste this code inside your webpack.dev.js file:

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

module.exports = merge(config, {
  mode: "development",
  devtool: "inline-source-map",
});
  • Paste the same code in the webpack.prod.js file but change the mode to 'production' and delete the devtool key.
// webpack.prod.js
const { merge } = require("webpack-merge");
const config = require("./webpack.config.js");

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

Step 4.

Update your package.json file to use the new configuration files:

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

Now simply execute npm run dev to see your changes

With this solution, you don't need to run build for every change and node_modules is excluded from the compiler.

You can read more about this solution webpack production mode

Victor Eke
  • 109
  • 6
-4

This worked for me:

exclude: [/bower_components/, /node_modules/]

module.loaders

A array of automatically applied loaders.

Each item can have these properties:

test: A condition that must be met

exclude: A condition that must not be met

include: A condition that must be met

loader: A string of "!" separated loaders

loaders: A array of loaders as string

A condition can be a RegExp, an absolute path start, or an array of one of these combined with "and".

See http://webpack.github.io/docs/configuration.html#module-loaders

freecks
  • 137
  • 4
  • 18
-6

try this below solution:

exclude:path.resolve(__dirname, "node_modules")
Jaimil Patel
  • 1,301
  • 6
  • 13
  • 15
    Welcome to StackOverflow. It would be better if you provided additional value on top of the other answers. In this case, your answer does not provide additional value, since another (Alan) user already posted that solution 5 years ago. You should vote it up once you have enough reputation – Oleg Valter is with Ukraine May 23 '20 at 12:04