Skip to content

Instantly share code, notes, and snippets.

@stevenslack
Last active September 30, 2021 14:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stevenslack/97efb012966e498d61a49aaebeef0784 to your computer and use it in GitHub Desktop.
Save stevenslack/97efb012966e498d61a49aaebeef0784 to your computer and use it in GitHub Desktop.
Webpack v4 -> v5 Update Guide

This guide is meant to serve as a reference for updating Webpack to version 5 for projects based off of the WP Starter theme using Webpack version 4. Many of the steps needed to update Webpack are not covered in the Webpack migration guide To v5 from v4 | webpack .

For the majority of the update you can use these two references:

To see what versions you are running and what the latest versions are you can run npm outdated in your terminal to see which packages need to be updated.

The sections below represent the different changes needed across your project:

devServer client/config/webpack/devServer.js

When updating the devServer configuration it may not be necessary to use broadways proxy server. This may change depending on your projects needs.

A handy guide to updating the webpack-dev-server from version 3 to version 4 (latest version that works with Webpack v5) can be found here: webpack-dev-server/migration-v4.md at master · webpack/webpack-dev-server · GitHub

Here are a couple of configuration changes that we use for the development mode of devServer for reference:

  • The disableHostCheck: true option was removed in favor of allowedHosts: ‘all’
  • contentBase/contentBasePublicPath/serveIndex/watchContentBase/watchOptions/staticOptions options were moved to static option:
- contentBase: '/client/build',
+ static: {
+     directory: '/client/build',
+ },
  • In order for hot module replacement to work properly and refresh in the browser you will want to add: liveReload: true and hot: true to the devServer options.
  • Some options from the previous WP Starter Theme devServer configuration may be removed in favor of the defaults. Some of these may include: host: ‘0.0.0.0’, and stats: { colors: true }
  • quiet and noInfo were removed without replacement as built-in logger is now used.
  • Since noInfo was removed from devServer there are other ways to achieve similar configurations. This option was to tell dev-server to suppress messages like the Webpack bundle information. Passing the —no-stats flag to the CLI in v5 can suppress bundle stats: webpack-cli/SERVE-OPTIONS-v4.md at master · webpack/webpack-cli · GitHub

entry client/config/webpack/entry.js

The Webpack entry configuration will also need to reflect the changes in devServer in order for HMR to work properly by using localhost. If your project is based off of the WP Starter Theme you will most likely make this change in client/config/webpack/entry.js in the getEntry function.

.map((currentValue) => (
  [
-    'webpack-dev-server/client?https://8080-httpsproxy.alley.test',
-    'webpack/hot/only-dev-server',
+    // Runtime code for hot module replacement
+    'webpack/hot/dev-server.js',
+    // Dev server client for web socket transport, hot and live reload logic
+    'webpack-dev-server/client/index.js',
+    // Add the entry point.
  ].concat(entry[currentValue])
))

output client/config/webpack/output.js

The Webpack output configuration changes will also need to reflect the changes made in devServer and entry with regards to using the localhost. The publicPath option for development mode can be changed from broadways proxy server to localhost:

- publicPath: 'https://8080-httpsproxy.alley.test/client/build/',
+ publicPath: 'https://localhost:8080/',

For production mode adding the clean: true option will allow the generated files in the output directory will be cleaned up when a production build is run. This option replaces the need for clean-webpack-plugin.

devTool client/config/webpack/devtool.js

Update the devTool configuration for development mode. The table on the Webpack devTool configuration guide provides examples of each available option for source maps. The eval-source-map will provide the original quality source map for development mode. It is slower than other options so you will need to evaluate which best suites your needs

plugins client/config/webpack/plugins.js

  • Updating the loaders and plugins for Webpack will require some removal of deprecated plugins and loaders being used. Additionally, using linters as plugins or loaders in the Webpack build process can greatly decrease the build performance of the build by more than half!

Therefore we recommend to use separate commands to run linters. These commands can be used in the buddy pipeline to prevent un-linted code from reaching production environments, but ultimately it is up to the developer to run these linters in their code and configure their IDEs to lint accordingly. Moving linters to separate commands is not covered in this guide.

These plugins should be removed from the Webpack plugins configuration (client/config/webpack/plugins.js):

  • Any Stylelint or ESLint plugin. In the case of the WP Starter Theme the stylelint-bare-webpack-plugin was removed.
  • optimize-css-assets-webpack-plugin For webpack v5 or above please use css-minimizer-webpack-plugin instead. Although, the css-minimizer-webpack-plugin may not be needed in the plugins configuration depending on your projects needs. The default production mode minimizers may suffice.
  • clean-webpack-plugin can be removed in favor of using output: { clean: true } as discussed above.
  • By setting devServer{ hot: true } the webpack.HotModuleReplacementPlugin({ ... }) configuration in the plugins configuration can be removed.

module.rules client/config/webpack/rules.js

If you are using Sass and PostCSS the latest configuration changes to the posts-loader will need to be updated:

{
  loader: 'postcss-loader',
  options: {
    sourceMap: true,
-    config: {
-      path: path.join(paths.config, 'postcss.config.js'),
+    postcssOptions: {
+      config: path.join(paths.config, 'postcss.config.js'),
    },
  },
},

The eslint-loader was deprecated and should be removed from your rules configurations. If you want run ESLint in your Webpack build use eslint-webpack-plugin and add this to your Webpack plugins configuration. Please note that running linters in your build can greatly slow the build process.

WP Assets client/config/webpack/wpAssets.js

Because of changes in the assets generated for HMR Webpack will generate a hot update chunk file. To prevent this file from being written to the assetMap.json file which is read by WordPress for asset enqueuing a rule can be written in the hasInvalidCharacters function in wpAssets.js. You can see the changes here: https://github.com/alleyinteractive/wp-starter-theme/pull/253/files#diff-7fb30ac5786433c3fefc463dfbf5c4837129493a2e707485d650c2cb07f05cc7R59-R73

Add the following to the hasInvalidCharacters function in wpAssets.js:

/*
 * Prevent the hot update chunk file name from 
 * being written to the assetMap.json file.
 *
 * The default string value is: '[id].[fullhash].hot-update.js',
 * which is what we are checking for.
 *
 * If you change hotUpdateChunkFilename in the output config
 * this will need to be updated here.
 *
 * @see https://webpack.js.org/configuration/output/#outputhotupdatechunkfilename
 */
if (value.includes('hot-update')) {
  return true;
}

Asset loading with WordPress inc/assets/php

  • These changes in the devServer require an update in the inc/assets.php file in order to work with localhost. The ai_get_asset_path function will set the path depending on which development mode you are working in. The reference to the proxy server here will need to be updated to use localhost.
$base_path = AI_ASSET_MODE === 'development' ?
-    'https://8080-httpsproxy.alley.test/client/build/' :
+    'https://localhost:8080/' :
    WP_STARTER_THEME_URL . '/client/build/';

Script Updates in package.json

It is not required but recommended that the webpack.config.js file is moved to the root directory for consistency. Additionally, moving this file will not require the —config flag in the Webpack script commands. Move the file to the root and update the path to the config directory.

// Config requires
- const getConfigService = require('./webpack');
+ const getConfigService = require('./client/config/webpack');

The most notable change in the Webpack commands will be to the dev command where webpack serve command can be called. The —no-inline option was removed.

- webpack-dev-server --mode development --no-inline
+ webpack serve --mode development --stats-colors

In order to prevent running scripts on the incorrect Node and NPM version you can prepend the check-node-version command to any script command. For example:

"build": "npx check-node-version --package && webpack --mode production",

Sass updates

You may encounter some breaking changes when updating Sass. For these changes you can reference this guide on the Sass website. If you remove node-sass from your dev dependencies you may get a warning that the node-sass-json-importer and the sass-resources-loader requires node-sass. However this warning is expected to be addressed in later releases.

Gotchas! The @use “sass:math”; should be used with single quotes otherwise you will get a SassError: SassError: Invalid Sass identifier “sass:math” while using the sass-resources-loader bundled with the wp-starter-theme. See: @use not working with builtin modules · Issue #148 · shakacode/sass-resources-loader · GitHub

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment