Polyfill node core modules in Webpack 5
Image Source: Picsum

Key Takeaways

Webpack 5’s removal of automatic Node.js polyfills often triggers breaking errors during migration. This guide demonstrates how to restore compatibility using ’node-polyfill-webpack-plugin’ for convenience or ‘resolve.fallback’ for granular, performance-focused control. It also provides a non-destructive workaround for Create React App users using ‘react-app-rewired’ to bypass default configuration limits.

  • Webpack 5 shifts responsibility for Node.js polyfills to the developer to minimize bundle size and avoid automatic inclusion of heavy browser-side shims.
  • The ’node-polyfill-webpack-plugin’ provides an efficient catch-all solution for projects that rely heavily on Node.js-specific APIs like ‘fs’ or ‘path’.
  • For optimized production builds, ‘resolve.fallback’ allows for surgical polyfilling of only the specific modules required by your dependencies.
  • Projects using Create React App (CRA) can implement these fixes via ‘react-app-rewired’, avoiding the need to eject while still modifying the underlying Webpack configuration.

Webpack 5 remove node core modules from bundle by default. This post will show you how to polyfill node core modules in Webpack 5.

Why polyfill node core modules?

While bundling you frontend code, you may use some node core modules like fs, path, crypto, etc. Webpack 5 remove node core modules from bundle by default. This is because node core modules are not available in browser. You may received error like this:

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by
default.This is no longer the case. Verify if you need this module and configure a
polyfill for it.

If you want to include a polyfill, you need to:
        - add a fallback 'resolve.fallback: { "assert": require.resolve("assert/") }'
        - install 'assert'
If you don't want to include a polyfill, you can use an empty module like this:
        resolve.fallback: { "assert": false }

   

How to polyfill node core modules?

There are two ways to polyfill node core modules in Webpack 5.

1. Use node-polyfill-webpack-plugin

node-polyfill-webpack-plugin is a Webpack plugin that polyfills node core modules. You can install it by running:

npm install node-polyfill-webpack-plugin --save-dev

 

This plugin will include all the code modules. If you want to polyfill specific modules then use second method.

Then add it to your webpack config as follow.

const NodePolyfillPlugin = require('node-polyfill-webpack-plugin')

module.exports = {
  // ...
  plugins: [new NodePolyfillPlugin()],
}

   

2. Use resolve.fallback

You can also use resolve.fallback to polyfill node core modules. For example, if you want to polyfill all module, you can add this to your Webpack config:


module.exports = {
  // ... other webpack config
resolve : {
  fallback: {
        // Use can only include required modules. Also install the package.
        // for example: npm install --save-dev assert
        url: require.resolve('url'),
        fs: require.resolve('fs'),
        assert: require.resolve('assert'),
        crypto: require.resolve('crypto-browserify'),
        http: require.resolve('stream-http'),
        https: require.resolve('https-browserify'),
        os: require.resolve('os-browserify/browser'),
        buffer: require.resolve('buffer'),
        stream: require.resolve('stream-browserify'),
    }
  },
  plugins: [
    new webpack.ProvidePlugin({
        process: 'process/browser',
        Buffer: ['buffer', 'Buffer'],
    })
  ]
}

   

In case of create-react-app:

If you are using create-react-app, there is no way to change Webpack config by default. So you can use react-app-rewired to override Webpack config. react-app-rewired let you change webpack config without ejecting. You can install it by running:

npm install react-app-rewired --save-dev

   

Then create a file named config-overrides.js in the root of your project:

const NodePolyfillPlugin = require('node-polyfill-webpack-plugin')

module.exports = function override(config, env) {
  // do stuff with the webpack config...
  config.plugins.push(new NodePolyfillPlugin())
  return config
}

   

To use the webpack config, you need to replace to your package.json start script with this:

{
  "scripts": {
    "start": "react-app-rewired start",
    "build": "react-app-rewired build",
    "test": "react-app-rewired test"
  }
}
The SQL Whisperer

The SQL Whisperer

Senior Backend Engineer with a deep passion for Ruby on Rails, high-concurrency systems, and database optimization.

Free cloud services for developer
Prev post

Free cloud services for developer

Next post

Retrying rest request with fetch

Retrying rest request with fetch