loading...
Cover image for Upgrade to Webpack 4

Upgrade to Webpack 4

olegchursin profile image Oleg Chursin ・3 min read

The app we are currently working on at Aon Cyber Solutions (1) is an ejected CRA with TypeScript and Apollo GraphQL. To our pleasure we have webpack.config.dev.js and webpack.config.prod.js to play with and must make sure that both environments are working as expected.

While getting all excited to update our Storybook to v.5, we discovered that our Webpack also needs a facelift. So the time has come to enter Webpack 4 era.

Visiting the official migration guide is your natural first call. Followed the step-by-step instructions to no avail and some frustration. Googling, StackOverflowing and GitHubbing to the rescue. Well, well… I’m not the only frustrated one.

Here comes a step-by-step guide that led to successful yarn start and yarn build:

Step 1. Upgrade webpack and install webpack-cli:

yarn add webpack
yarn add webpack-cli

version check:

// package.json
...
"webpack": "^4.29.6",
"webpack-cli": "^3.2.3",
...

Step 2. Add respective modes in webpack.config.dev.js and webpack.config.prod.js

// webpack.config.dev.js
...
module.exports = {
    mode: 'development',
    ...
// webpack.config.prod.js
...
module.exports = {
    mode: 'production',
    ...

Step 3. Add fork-ts-checker-notifier-webpack-plugin

yarn add fork-ts-checker-notifier-webpack-plugin --dev

version check:

// package.json
...
"fork-ts-checker-notifier-webpack-plugin": "^1.0.0",
...

Step 4.1 Update html-webpack-plugin

yarn add html-webpack-plugin@next

version check:

// package.json
...
"html-webpack-plugin": "^4.0.0-beta.5",
...

Step 4.2 Adjust the plugin order in webpack.config.dev.js and webpack.config.prod.js

Make sure HtmlWebpackPlugin comes before InterpolateHtmlPlugin and the latter is declared as in the example below:

plugins: [
  new HtmlWebpackPlugin({
    inject: true,
    template: paths.appHtml
  }),
  new InterpolateHtmlPlugin(HtmlWebpackPlugin, env.raw),
...

Step 5. Update ts-loader, url-loader and file-loader

yarn add url-loader file-loader ts-loader

version check:

// package.json
...
"file-loader": "^1.1.11",
"ts-loader": "4.0.0",
"url-loader": "0.6.2",
...

Step 6. Update react-dev-utils

yarn add react-dev-utils

version check:

// package.json
...
"react-dev-utils": "6.1.1",
...

Step 7. Sub extract-text-webpack-plugin with mini-css-extract-plugin

Get rid of extract-text-webpack-plugin altogether. Add and configure mini-css-extract-plugin.

yarn add mini-css-extract-plugin

version check:

// package.json
...
"mini-css-extract-plugin": "^0.5.0",

Config:

// webpack.config.prod.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

plugins: [
  ...
  new MiniCssExtractPlugin({
    filename: "[name].css",
    chunkFilename: "[id].css"
  }),
  ...
],
module: {
  rules: [
    {
      test: /\.css$/,
      use: [
      {
        loader: MiniCssExtractPlugin.loader,
        options: {
        // you can specify a publicPath here
        // by default it use publicPath in webpackOptions.output
        publicPath: '../'
      }
    },
    "css-loader"
  ]
},

Step 8. Update and reconfigure uglifyjs-webpack-plugin

yarn add uglifyjs-webpack-plugin --dev

version check:

// package.json
...
"uglifyjs-webpack-plugin": "^2.1.2"

Config:

// webpack.config.prod.js
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
module.exports = {
  ...
  optimization: {
    minimizer: [new UglifyJsPlugin()],
  },
...

Step 9. Fix any deprecation errors you may be getting. Follow the error message and trace and update any webpack plugins you may need to. In our case it was webpack-manifest-plugin.

I really hope this guide will save at least someone a few minutes/hours.


(1) This is a personal blog post that in no way reflects Aon Cyber Solution’s official opinion.


Sources that were used to come up with the working solution:

Discussion

pic
Editor guide
Collapse
pigozzifr profile image
Francesco Pigozzi

Good job!🦄