How to upgrade Webpack from v3 to v5.

Aleksandr Zakharov
3 min readSep 16, 2020

--

Ticket regarding webpack v3 upgrade was in our Jira for more than 2 years. I’ve tried to upgrade it to v4 earlier but it wasn’t possible due to the structure of our project.

What’s wrong with webpack 4?

Webpack v4 changed the chunking mechanism completely and dropped the support of shared modules from entry points. CommonChunkPlugin has been deprecated as well. And the new built-in implementation of chunking wasn’t suitable for our project structure because of shared modules.

So… a feature ticket had been raised: https://github.com/webpack/webpack/issues/6977. And based on the discussion there webpack 5 obtained dependOn property for entry point configuration which is allowing us to share bundles across the entry points. Now we are good to go with it.

Webpack 4 is still lacking this feature though…

My environment:

  • Webpack configuration with shared modules(bundles) in entry points.
  • Separate docker container with frontend.
  • AWS CodeBuild.

Motivation:

  • Optimize the time of building.
  • Caching built-in support to optimize speed of build in case of small changes.

What needs to be changed in webpack configuration:

  1. UglifyJsPlugin has to be removed. Now TerserWebpackPlugin is a default choice.
  2. ExtractTextPlugin has to be replaced with MiniCssExtractPlugin.
  3. CommonChunkPlugin must be removed. Now the mechanism of chunking is different and has built-in support under the optimization section of config. You need to take a look at https://webpack.js.org/configuration/optimization/ to make it suit your needs. But I personally didn’t do any config at all. Default one worked out perfectly.
  4. You need to make changes to your entry points if you are using any shared modules(bundles) https://webpack.js.org/guides/code-splitting/#entry-dependencies.

List of packages I’ve updated or installed:

  1. webpack: 5.0.0-beta.28
  2. webpack-cli: 3.3.12
  3. css-loader: 4.3.0
  4. file-loader: 6.1.0 (because we use file-loader) and new version raise appropriate errors if problems occur on compilation stage.
  5. mini-css-extract-plugin: 0.10.0

webpack: 5.0.0-beta.29 started complaining about babel-core. So we had to downgrade to 28. Be careful.

So the main part is done by now. You may require some package updates or small tweaks based on your particular case. But it should be pretty painless.

Cache support:

I’ve just used the default configuration:

cache: {
// this means that cache will be stored in a filesystem
type: "filesystem",
// directory to store cache
cacheDirectory: '/frontend/webpack_cache',
// list of dependencies which need to be considered
buildDependencies: {
// webpack config file itself
config: [ __filename ]
}
}

And because I’m running this config in an AWS CodeBuild I’ve created a new bucket for cache. So before each build of a frontend you need to populate /frontend/webpack_cache direcory with files downloaded from s3.

After receiving the cache we are:

  1. Building an image.
  2. Creating the frontend container from it.
  3. Getting updated cache from the container .
docker cp "frontend:/frontend/webpack_cache" "${FRONTEND_DIR}"

4. Pushing updated version back to s3.

5. PROFIT!

In our particular case we’ve managed to reduce webpack build time from 8 to 3 minutes at worst case. And to 30 seconds for small changes(because of cache).

Caveat:

We are getting this error:

No serializer registered for CssDependency

And it’s not resolved as of 5.0.0-beta.29.
This resulted into fontawesome import error in case of using cache and not a new build. So we had to include these fonts as an external dependency. Be prepare for such obstacles.

Apart from that it’s all working perfectly now.
Hope you found my experience useful for yourself.

--

--