14

I'd like the same functionality like RequireJS empty: http://requirejs.org/docs/optimization.html#empty

My use-case is that I include jquery-migrate in development, but I'd like to exclude this when built for production.

Using IgnorePlugin just makes it not included, and when requireing it in the code, it then throws an error (Uncaught Error: Cannot find module "jquery-migrate").

What I'd like to happen is for it to just return undefined, or something of the like (like empty: in RequireJS). Id like to not touch the import in the code, just configuring it to return undefined.

EDIT: Using NormalModuleReplacementPlugin works, if I point the replacement to an empty file. But keeping an empty file around just for this seems unnecessary.

SimenB
  • 6,410
  • 2
  • 23
  • 27

3 Answers3

20

I use the null-loader for blanking out modules. The noop-loader can be used for a less awkward if-else in the config.

Try:

rules: [{
    test: /jquery-migrate/,
    use: IS_DEV ? 'null-loader' : 'noop-loader'
}]
Rick
  • 508
  • 4
  • 9
  • This seemed to work for me and I think answers OP's question best. No change to code, I still have a `import foo fro 'excluded-module'` at the top of my code with no funny `if (DEV)` wrapper. Imagine `require('excluded-module')` works just as well. – thom_nic Dec 03 '15 at 17:28
  • 3
    Note to other newbies, these loaders aren't included in webpack: `npm install --save-dev null-loader && npm install --save-dev noop-loader` – diachedelic Apr 06 '17 at 16:16
  • Is there a way without modules? I just tried ```loader: () => {}``` and I still get a can't resolve error. – Sophie McCarrell Jul 12 '17 at 17:34
5

You can try to make a resolve.alias in webpack.config:

resolve: {
    alias: {
         "jquery-migrate": process.env.NODE_ENV === 'production' ? "empty-module": "jquery-migrate"
    }
}
Peter Kese
  • 51
  • 1
1

Use Webpack's DefinePlugin in combination with the normal production plugins (Dedupe and Uglify).

Then in your code you can write:

if(DEBUG) {
    var test = require('test');
    alert(test);
}

And when it's built in production, the DEBUG will be replaced with a literal if(false) { ... } which will be completely removed by the uglify plugin, so test will only be required in a debug build.

Here's a sample Grunt task config for grunt-webpack that has development and production targets for the task:

        development: {
            devtool: "sourcemap",
            output: {
                pathinfo: true,
            },
            debug: true,
            production: false,
            plugins: [
                new webpack.DefinePlugin({
                    DEBUG: true,
                    PRODUCTION: false
                })
            ]
        },

        production: {
            plugins: [
                new webpack.DefinePlugin({
                    DEBUG: false,
                    PRODUCTION: true
                }),
                new webpack.optimize.DedupePlugin(),
                new webpack.optimize.UglifyJsPlugin({
                    output: {
                        comments: false,
                    }
                })
            ]
        },
Jonathan Dumaine
  • 5,575
  • 3
  • 38
  • 50
  • I actually prefer decorating source code with debug statements rather than in build tool scripts. It makes it far more understandable for yourself after coming back to the code and others when trying to understand where that jQuery-migrate is coming from. – Jonathan Dumaine Apr 22 '15 at 13:31
  • True. This doesn't work cleanly for AMD though, at least if listed in the original `define` call. Using an alias is exactly like `empty:`, except i have to create the `empty` module myself. – SimenB Apr 22 '15 at 13:39