Search code examples
webpackwebpack-2

Webpack 2.2.0 with Module.noParse doesn't transpile 'require' of externals


I'm moving from Webpack 1.x to 2.x and faced trouble. I would like to have all my vendor's libs be ignored by Webpack, because I prepared them by gulp.

In webpack.config.js I have module.noParse like:

noParse: /react|react-dom|redux|react-redux|lodash/

And I have externals section:

externals: {
    'react': 'React',
    'react-dom': 'ReactDOM',
    'redux': 'Redux',
    'react-redux': 'ReactRedux',
    'lodash': '_',
}

So, in Webpack 1.x it works perfectly, but version 2.2.0 gives:

var _react = require('react');

Uncaught ReferenceError: require is not defined`

If I delete the noParse rule, webpack will include vendors in package and everything will be wrapped with var react = webpack_require and works fine.


Solution

  • Webpack 2 is stricter than its predecessor. It's hinting to you that you're likely misconfiguring it.

    • noParse by design throws if you try to use it on a library containing require and other module calls.

    • externals tells the bundler not to step into external packages but instead replace the imports of them with a global variable.

    Therefore, externals is all you need.


    Cleaner approach

    I'd recommend dropping the gulp task altogether and move your react / lodash bundling into a Webpack vendor chunk. Use the expose-loader to export the modules on global window variables.

    The following config should do it:

    module.exports = {
      entry: {
        "vendor": [
          "expose-loader?React!react",
          "expose-loader?ReactDOM!react-dom",
          "expose-loader?Redux!redux",
          "expose-loader?ReactRedux!react-redux",
          "expose-loader?_!lodash"
        ],
        "app": "./app/index.js"
      },
      externals: {
        'react': 'React',
        'react-dom': 'ReactDOM',
        'redux': 'Redux',
        'react-redux': 'ReactRedux',
        'lodash': '_',
      },
      "plugins": [
        new webpack.optimize.CommonsChunkPlugin({ name: "vendor", minChunks: Infinity }))
      ],
      /* other options... */
    }
    

    Ensure you npm i -D expose-loader and add a script to your page with src attribute set to url of vendor.js