TLDR;

The final config looked like this:

# package.json
"devDependencies": {
    ...
    "process": "0.11.10"
}

# webpack.config.js
module.exports = {
  ...
  plugins: [
      new webpack.ProvidePlugin({
             process: 'process/browser',
      }),
  ],
}

Let me preface this by saying I am not a Webpack/Javascript guru. Far from it. I have very little prior knowledge and rely solely on documentation and web search skills to get me to the goal.

Due to a recent security vulnerability in one of our webpack plugins, we decided to look into upgrading from Webpack 4.43.x to Webpack 5. We fully expected there to be issues, it’s a major version after all. However, the rabbit hole I fell into was slightly different than what I had envisioned.

First of all, what is Webpack. If you develop in the Javascript world, you probably know about it, if you don’t, it’s an asset bundler. It takes all of your static assets and, well, bundles them for better delivery and performance. It is a very popular, well-loved and well-maintained open source project.

Because it’s such a nice project, it has a migration guide. I was thrilled to see this. I was even more thrilled when I easily started checking things off it:

  • Node 10+
  • Upgrade to latest 4.x.x webpack version, no errors or warnings
  • Using HtmlWebpackPlugin
  • Setting mode
  • Don’t use any affected settings
  • Successful build with webpack compatibility config

Amazing! All that’s left is to upgrade! So I did. And then the build didn’t run. Turns out, at the time of the upgrade, Webpack had just released a new beta version, which introduced a breaking change that affected one of our plugins. After a bit of digging, I pinned the webpack version to the one before that and reran the install and build. And it worked!

Except, there was a warning about path and polyfills. The upgrade guide does not mention anything about this, but Webpack 5 no longer auto loads polyfills for code node libraries. (Beta feedback). They did a community consultation on it and everything. The module that was erroring out was path. The error suggested a course of action (aliasing to false), which worked, and the build succeeded.

The integration tests did not. Turns out there was this one page that used this one library, which was a third-level dependency that we couldn’t get rid of, which required the process node library in the browser. This is where I spent almost 2 days. The library had an issue on it which at the time did not help me much. (I have since posted a comment with my findings to that issue, hoping to save at least one soul.) “Just polyfill process” meant nothing to me and it looked like that issue predated Webpack 5 anyway, so it wouldn’t have been a problem for the majority of people using the library.

I went on a wild goose chase trying to figure out how to polyfill process. My first problem was figuring out what the library I need was called. There are a few libraries named as if they’d be the right thing, but none of them worked. In the end I went and dug through Webpack code to find the list of modules they were no longer loading so I could find what the process one was. It’s process/browser and the library is process. Cool, that’s fine. But how do you polyfill it?

I spent way too long moving things around in my our webpack config. Web searchers were not fruitful, it almost looked like nobody had needed to do this again. Granted, I may have been in a niche group, upgrading to a beta version and having a dependency I couldn’t get rid of which doesn’t work with that version without some kind of magical custom config.

To cut a very long and boring story short, try shimming instead. With the right library and the right config, I had the site working within 5 minutes.