Upgrade to Webpack 4
Tags: webpack, react, javascript
Published: 2019-03-09 02:39:45

---
title: Upgrade to Webpack 4
published: true
description: Upgrading to Webpack 4 can be a mess, here's how we did it.
tags: webpack, react, javascript
cover_image: https://thepracticaldev.s3.amazonaws.com/i/4g38g2zt22i82uds3jdz.png
---


The app we are currently working on at [Aon Cyber Solutions](https://www.aon.com/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](https://webpack.js.org/migrate/4/) 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. <sigh>

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:

```json
// 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`

```javascript
// webpack.config.dev.js
...
module.exports = {
    mode: 'development',
    ...
```
```javascript
// 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:

```json
// 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:

```json
// 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:

```javascript
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:

```json
// 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:

```json
// 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:

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

Config:

```javascript
// 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:

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

Config:

```javascript
// 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:**

* [https://webpack.js.org/migrate/4/](https://webpack.js.org/migrate/4/)
* http://garyzhangblog.cn/2018/12/31/20181231webpack4/
* https://github.com/Realytics/fork-ts-checker-webpack-plugin/issues/154
* https://github.com/TypeStrong/ts-loader/issues/726
* https://github.com/webpack/webpack/issues/6244
* https://github.com/webpack-contrib/mini-css-extract-plugin/tree/b653641e7993eb28fad70c1733dc45feafea93c5
* https://webpack.js.org/plugins/uglifyjs-webpack-plugin/
* https://thebrainfiles.wearebrain.com/moving-from-webpack-3-to-webpack-4-f8cdacd290f9
* https://github.com/webpack/webpack/issues/6568
* https://gist.github.com/gricard/e8057f7de1029f9036a990af95c62ba8
* https://www.npmjs.com/package/webpack-dev-server
* https://github.com/webpack-contrib/mini-css-extract-plugin
* https://www.npmjs.com/package/file-loader
* https://www.npmjs.com/package/webpack-manifest-plugin