Engineering

Migrating from Webpack 3 to 4

Posted by Adam Jahnke

We are big fans of webpack at AppOptics. It is a very capable tool with lots of flexibility. After hearing lots of stories about the large performance improvements of webpack 4 beta, when the final release came out, we were eager to migrate our project from v3.

The webpack configuration can be difficult to understand, and unfortunately, the webpack team was trying to hit a deadline and was unable to write any migration documentation before the v4 release. Lucky for you, we decided to push through anyway, and we took notes.

For more info about the release, check out

Upgrade node to 8.9.4

To get the best performance out of v4, @wSokra says use at least node 8.9.4.

Upgrade webpack

The webpack solution’s core functionality and CLI code have been split into two repos now.

$ npm i -D webpack webpack-cli

Use a mode

You may see an error like The 'mode' option has not been set. Set 'mode' option to 'development' or 'production' to enable defaults for this environment.

In v4, you have to set a mode in your config.

{
  mode: "production",
}

It can also be set when invoked from CLI.

$ webpack --mode production

Change CommonsChunkPlugin to splitChunks

You may see an error like Error: webpack.optimize.CommonsChunkPlugin has been removed, please use config.optimization.splitChunks instead.

The CommonsChunkPlugin is an opt-in feature that creates a separate file (known as a chunk) consisting of common modules shared between multiple entry points.

This functionality has moved from the CommonsChunkPlugin to the optimization.splitChunks setting.

Previously in v3, we used runtime and vendor chunks like so.

{
  plugins: [
    new webpack.optimize.CommonsChunkPlugin({
      name: ["runtime"],
      minChunks: Infinity,
    }),
    new webpack.optimize.CommonsChunkPlugin({
      name: "vendor",
      minChunks: ({ resource }) => /node_modules/.test(resource),
    }),
  ]
}

In v4, this roughly translates to…

{
  optimization: {
    runtimeChunk: "single", // enable "runtime" chunk
    splitChunks: {
      cacheGroups: {
        vendor: {
          test: /[\\/]node_modules[\\/]/,
          name: "vendor",
          chunks: "all"
        }
      }
    }
  }
}

More information about the new optimization.splitChunks option can be found here.

Get rid of ModuleConcatenationPlugin

Also known as “scope hoisting,” the ModuleConcatenationPlugin is now on by default in production mode.

Change UglifyJsPlugin

You may see an error like Error: webpack.optimize.UglifyJsPlugin has been removed, please use config.optimization.minimize instead.

V4 now handles dead code elimination internally. Both it and minimization are on by default in production mode, but to continue tuning Uglify settings, add the uglifyjs-webpack-plugin.

$ npm i -D uglifyjs-webpack-plugin

And in the optimization.minimizer section.

const UglifyJsPlugin = require("uglifyjs-webpack-plugin");

{
  optimization: {
    minimizer: [
      new UglifyJSPlugin({
        sourceMap: true,
        uglifyOptions: {
          ...
        }
      })
    ]
  }
}

Upgrade loaders

You may see an error like Module build failed: TypeError: Cannot read property 'eslint' of undefined

This happened for us with eslint-loader and file-loader. Just upgrade the loaders.

$ npm i -D eslint-loader file-loader

The SolarWinds trademarks, service marks, and logos are the exclusive property of SolarWinds Worldwide, LLC or its affiliates.  All other trademarks are the property of their respective owners.

© 2018 SolarWinds Worldwide, LLC. All rights reserved.