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"
  }
}