Saber
Saber

Reputation: 4719

How to Polyfill node core modules in webpack 5

webpack 5 no longer do auto-polyfilling for node core modules. How to fix it please?

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.

errors

Upvotes: 462

Views: 692038

Answers (30)

Maqsood Ahmed
Maqsood Ahmed

Reputation: 2257

I was also getting these errors when upgrading from webpack v4 to v5. Resolved by making the following changes to webpack.config.js

  • Added resolve.fallback property

  • Removed node property

{
    resolve: {
      modules: [...],
      fallback: {
        "fs": false,
        "tls": false,
        "net": false,
        "path": false,
        "zlib": false,
        "http": false,
        "https": false,
        "stream": false,
        "crypto": false,
        "crypto-browserify": require.resolve('crypto-browserify'), //if you want to use this module also don't forget npm i crypto-browserify 
      } 
    },
    entry: [...],
    output: {...},
    module: {
      rules: [...]
    },
    plugins: [...],
    optimization: {
      minimizer: [...],
    },
    // node: {
    //   fs: 'empty',
    //   net: 'empty',
    //   tls: 'empty'
    // },
}

upgrade from v4 to v5 => https://webpack.js.org/migrate/5/#clean-up-configuration

Upvotes: 182

PhoenixPan
PhoenixPan

Reputation: 551

In case you're using create-react-app, you can use craco to expose webpack config and add this to craco.config.js:

module.exports = {
  webpack: {
    configure: (webpackConfig, { env }) => {
      webpackConfig.resolve.fallback = {
        http: false,
        https: false,
        //other stuff needs polyfill
      };
    }
  }
}

You could either do https: false or https: require('https-browserify') depends on your needs.

Upvotes: 0

Chidiebere Ezeokwelume
Chidiebere Ezeokwelume

Reputation: 139

If you're having this error on your react app, webpack.config.js would not help you override the webpack config. You have to use craco to solve this and then run your project with craco ie

    craco.config.js

     const path = require('path');
     module.exports = {
      webpack: {
       configure: {
        resolve: {
         fallback: {
          crypto: require.resolve('crypto-browserify'),
         },
        },
       },
      },
     };

Then you run your react app on craco ie

    package.json
 
    "scripts": {
     "start": "craco start",
     "build": "craco build",
    },

Upvotes: 0

Abdulhakim
Abdulhakim

Reputation: 748

I had a React.js and Firebase app and it was giving the same error. I solved my issue by removing require('dotenv').config();. New React.js versions automatically handles loading packages like dotenv.

This polyfill error is not only with dotenv package but also with some other packages. So, if you have some loading statements as above, you can remove them and retry again.

Upvotes: 1

Gift Ntokozo Mavuso
Gift Ntokozo Mavuso

Reputation: 427

if you are using create-react-app with craco then configuration in craco.config.js should be like this:

module.exports = {
  webpack: {
      configure: {
        resolve: {
          fallback: {
            "path": require.resolve("path-browserify")
          },
        },
      },
    },
}

Upvotes: 0

Manit
Manit

Reputation: 1105

Though this answer doesn't directly deal with the polyfill but sometimes one should evaluate if you really need a library which needs a polyfill at first place. We shouldn't reinvent the cycle but at the same time this comes with some disadvantages particularly when you are trying to migrate from one version to another. I faced a very similar issue while upgrading from Angular 7 to 12. In my case, in one of the components we were using util.isArray. The solution was to replace util.isArray to Array.isArray and remove the util import from the component. This not only helped in getting rid of the library but also ensured that we wouldn't have to polyfill.

Upvotes: -2

Ruben Daddario
Ruben Daddario

Reputation: 1122

For those still doing configuration through react-app-rewired's config-overrides.js file, this will work:

config-overrides.js

const { override, addWebpackPlugin } = require('customize-cra')
const NodePolyfillPlugin = require("node-polyfill-webpack-plugin")

module.exports = override(addWebpackPlugin(new NodePolyfillPlugin()))

package.json

...
"dependencies": {
    ...
    "customize-cra": "^1.0.0",
    "node-polyfill-webpack-plugin": "^2.0.1"
  },

This will inject node-polyfill-webpack-plugin as a webpack 5 plugin.

Upvotes: 2

10KNOOB
10KNOOB

Reputation: 43

I tried to follow as many solutions as I can. But Surprisingly none of them work for me. Except for the downgrade option. But that creates another problem. Framer motion was not working in that node version. So tried to follow the console log. After opening that I find out the stream was missing there. So Simply I install that dependency using (npm i stream). And fixed the problem. Maybe it's different for you. But just installing the missing dependency will solve the problem instead of writing a few more lines of code.

Upvotes: -1

Magnetto90
Magnetto90

Reputation: 164

My solution for #VUE

const { defineConfig } = require('@vue/cli-service')
const webpack = require('webpack');
module.exports = defineConfig({
  configureWebpack: {
    plugins: [
      new webpack.ProvidePlugin({
        Buffer: ['buffer', 'Buffer'],
      }),
      new webpack.ProvidePlugin({
          process: 'process/browser',
      })
    ],
    resolve: {
      fallback: {
        "os": require.resolve("os-browserify/browser"),
        "url": require.resolve("url/"),
        "crypto": require.resolve("crypto-browserify"),
        "https": require.resolve("https-browserify"),
        "http": require.resolve("stream-http"),
        "assert": require.resolve("assert/"),
        "stream": require.resolve("stream-browserify"),
        "buffer": require.resolve("buffer")
      }
    }
  },

  transpileDependencies: [
    'vuetify'
  ]

})

Upvotes: 10

jmac
jmac

Reputation: 125

All other answers are missing one important piece: how NOT to polyfill the node core modules. In case the error comes from some module in dependency of dependency of your dependency, which you actually do not need, you can quite safely ignore it. In that case, the most simple workaround is to add to your package.json these lines:

"browser": {
  "fs": false,
  "path": false,
  "os": false
}

And similarly for other core node modules if you need to ignore them.

This approach works great for frameworks where the actual webpack config is not directly accessible by default (like Angular).

I have found this solution when looking for a different error.

Upvotes: 3

Vitto
Vitto

Reputation: 1089

As per Web3 documentation:

If you are using create-react-app version >=5 you may run into issues building. This is because NodeJS polyfills are not included in the latest version of create-react-app.

Solution:

Install react-app-rewired and the missing modules

If you are using yarn:

yarn add --dev react-app-rewired crypto-browserify stream-browserify assert stream-http https-browserify os-browserify url buffer process

If you are using npm:

npm install --save-dev react-app-rewired crypto-browserify stream-browserify assert stream-http https-browserify os-browserify url buffer process

Create config-overrides.js in the root of your project folder with the content:

const webpack = require('webpack');

module.exports = function override(config) {
    const fallback = config.resolve.fallback || {};
    Object.assign(fallback, {
        "crypto": require.resolve("crypto-browserify"),
        "stream": require.resolve("stream-browserify"),
        "assert": require.resolve("assert"),
        "http": require.resolve("stream-http"),
        "https": require.resolve("https-browserify"),
        "os": require.resolve("os-browserify"),
        "url": require.resolve("url")
    })
    config.resolve.fallback = fallback;
    config.plugins = (config.plugins || []).concat([
        new webpack.ProvidePlugin({
            process: 'process/browser',
            Buffer: ['buffer', 'Buffer']
        })
    ])
    return config;
}

Within package.json change the scripts field for start, build and test. Instead of react-scripts replace it with react-app-rewired before:

"scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
},

after:

"scripts": {
    "start": "react-app-rewired start",
    "build": "react-app-rewired build",
    "test": "react-app-rewired test",
    "eject": "react-scripts eject"
},

The missing Nodejs polyfills should be included now and your app should be functional with web3.

If you want to hide the warnings created by the console:

In config-overrides.js within the override function, add:

config.ignoreWarnings = [/Failed to parse source map/];

Upvotes: 89

Sameer Kesava
Sameer Kesava

Reputation: 136

For me (using React => v17; React scripts=> v5; webpack => v5), a combination of solutions suggested by @Letton and @Richie Bendall worked along with another addition, i.e. to the package.json, the following packages had to be added and installed. Please also note that fs version "^2.0.0" throws an error, so changed to "0.0.1-security".

"assert": "^2.0.0", 
"https-browserify": "^1.0.0", 
"os": "^0.1.2",
"os-browserify": "^0.3.0",
"react-app-rewired": "^2.1.9",
"stream-browserify": "^3.0.0",
"stream-http": "^3.2.0",
"fs":"^0.0.1-security",
"crypto-browserify": "3.12.0",
"buffer":"^6.0.3",
"node-polyfill-webpack-plugin": "^2.0.1"

After installation of these, executing the remaining steps, i.e. adding config-overrides.js to the root directory and changing scripts content in package.json from react-scripts to react-app-rewired fixed the problem.

Upvotes: -2

therightstuff
therightstuff

Reputation: 1007

I'm using create-react-app with craco, and I encountered the following errors when upgrading to webpack 5:

'buffer'


Module not found: Error: Can't resolve 'buffer' in '/Users/therightstuff/my-project/node_modules/safe-buffer'

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: { "buffer": require.resolve("buffer/") }'
    - install 'buffer'
If you don't want to include a polyfill, you can use an empty module like this:
    resolve.fallback: { "buffer": false }

This was resolved simply by installing the buffer package with npm install -D buffer.

'fs'


Module not found: Error: Can't resolve 'fs' in '/Users/therightstuff/my-project/node_modules/line-navigator'

This was resolved by setting a webpack fallback in the craco configuration craco.config.js:

module.exports = {
    style: {
        postcssOptions: {
            plugins: [
            require('tailwindcss'),
            require('autoprefixer'),
            ],
        },
    },
    webpack: {
        configure: (webpackConfig, { env, paths }) => {
            // eslint-disable-next-line no-param-reassign
            webpackConfig.resolve.fallback = {
                fs: false,
            };
            return webpackConfig;
        },
    },
}

Upvotes: 5

kennisnutz
kennisnutz

Reputation: 433

I tried this https://stackoverflow.com/a/71803628/15658978 solution and it solved the problem form me.

simply run the following 2 commands

npm uninstall react-scripts
npm install [email protected]

Upvotes: 1

Jivn Shet
Jivn Shet

Reputation: 35

Faced the same issue, here's a solution:

  1. Remove package-lock.json from the project folder and npm uninstall webpack
  2. Downgrade react-script from to 4.0.3
  3. Make sure package-lock.json is deleted/removed
  4. Install webpack using npm install [email protected]
  5. Finally, run npm install using the terminal

Upvotes: 1

hirenVaishnav
hirenVaishnav

Reputation: 39

I got this error while imported Router from express import { Router } from 'express';

Resolved after correction import { Router } from '@angular/router';

Upvotes: 3

R3verse
R3verse

Reputation: 79

I found a solution that worked for me:

  1. npm uninstall webpack
  2. delete the "package-lock.json" file
  3. npm install [email protected] --force
  4. include in the "package.json" file the following in your "scripts":
    "scripts": {
        "start": "SET NODE_OPTIONS=--openssl-legacy-provider && react-scripts start",
        "build": "SET NODE_OPTIONS=--openssl-legacy-provider && react-scripts build",
        "test": "react-scripts test",
        "eject": "react-scripts eject"
    }
    

Upvotes: 2

STUBORN Stopee
STUBORN Stopee

Reputation: 1

my problem was that I was trying to use JSON.parse, then when I started writing , auto complete showed me json(note small letters) though I renamed it to JSON. when I pressed enter it automatically imported (import { json } from "express/lib/response";) it was the cause and I didn't notice it at all , later in development my app was crushing and it took me about six hours to note, since the app is quite big.

so if none of the above solutions work just see if you didn't import something .

Upvotes: -1

Richie Bendall
Richie Bendall

Reputation: 9152

Re-add support for Node.js core modules with node-polyfill-webpack-plugin:

With the package installed, add the following to your webpack.config.js:

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

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

Upvotes: 130

Raz Asido
Raz Asido

Reputation: 28

for me, I just removed an unused import called:

import res from "express/lib/response"

and it fixed it!

Upvotes: -2

Swaroop Maddu
Swaroop Maddu

Reputation: 4844

Method 1

  • Open project/node_modules/react-scripts/config/webpack.config.js

  • In fallback add "crypto": require.resolve("crypto-browserify")

resolve: {
   fallback: {
       "crypto": require.resolve("crypto-browserify")
   }
} 
  • Install npm i crypto-browserify
  • Restart your app.

Above method doesn't work if you commit since we aren't node_modules

Method 2

  • Install patch-package: yarn add patch-package

  • Install the needed pollyfills.(do an initial build of your application and it will tell you.)

  • Modify node_modules/react-scripts/config/webpack.config.js. Here's an example. This is taken from Webpack's docs.

module.exports = {
  //...
  resolve: {
    fallback: {
      assert: require.resolve('assert'),
      buffer: require.resolve('buffer'),
      console: require.resolve('console-browserify'),
      constants: require.resolve('constants-browserify'),
      crypto: require.resolve('crypto-browserify'),
      domain: require.resolve('domain-browser'),
      events: require.resolve('events'),
      http: require.resolve('stream-http'),
      https: require.resolve('https-browserify'),
      os: require.resolve('os-browserify/browser'),
      path: require.resolve('path-browserify'),
      punycode: require.resolve('punycode'),
      process: require.resolve('process/browser'),
      querystring: require.resolve('querystring-es3'),
      stream: require.resolve('stream-browserify'),
      string_decoder: require.resolve('string_decoder'),
      sys: require.resolve('util'),
      timers: require.resolve('timers-browserify'),
      tty: require.resolve('tty-browserify'),
      url: require.resolve('url'),
      util: require.resolve('util'),
      vm: require.resolve('vm-browserify'),
      zlib: require.resolve('browserify-zlib'),
    },
  },
};
  • Don't add all of them, add only the ones you need.

Make sure you install the packages first before modifying the webpack config.

  • Run yarn patch-package react-scripts. This will generate a patch (this should be committed in your repo going forward).

  • Add a postinstall script to package.json: "postinstall": "yarn patch-package". Now, anytime, someone installs npm deps on this project, will get the patch you created in step 3 applied automatically.

  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject",
    "postinstall": "yarn patch-package"
  },

Upvotes: 10

Jes&#250;s Fuentes
Jes&#250;s Fuentes

Reputation: 919

This is happening with the new vue-cli upgrade (v5). In order to fix it (the empty modules way), you have to change vue.config.js this way:

configureWebpack: (config) => {
  config.resolve.fallback = {
    ...config.resolve.fallback,
    // Include here the "empty" modules
    url: false,
    util: false,
    querystring: false,
    https: false,
  };
}

Upvotes: 2

Gavin
Gavin

Reputation: 321

Secret's answer very nearly worked for me (I don't have enough reputation yet to comment on there, sorry!)

After having followed the steps in their answer it then told me that because of the difference in required versions of eslint, I should add SKIP_PREFLIGHT_CHECK=true to a .env file in the project, so I just added it to my existing one.

It would then successfully build (finally!) But then I noticed, in Chrome at least, that I couldn't click on anything or even select any text. Turns out that there's still an Iframe over the top of everything that can be removed in Inspector. - This applies when running a dev build, npm run start, I am not sure if it does it on a production build.

I must say this sudden change IMO really hasn't been very well thought through!

Upvotes: 0

Noud
Noud

Reputation: 145

With create-react-app v17 and scripts 5.0.0 you need to add a fallback to your webpack.config.js and install 'process'.

   `module.exports = function (webpackEnv) {
      .........
      return {
       .........
      resolve: {
      ..........
      fallback: { "process": require.resolve("process/browser") },`

Upvotes: 0

Adesiyan Tope
Adesiyan Tope

Reputation: 49

npm install assert --save

npm install buffer --save

For anyone facing similar issue, just install the missing modules. These modules are reported as missing because they are part of node.js, but are available separately also via the npm.

Upvotes: 1

Ballo Ibrahima
Ballo Ibrahima

Reputation: 627

If it's Twilio you use:

The Twilio module is not intended for use in client-side JavaScript, which is why it fails for your Angular application. Twilio uses your Account SID and your Auth Token, the use in the client side represents a risk; So the best is to use it on the server side and to use the API.

Upvotes: 0

thisLinda
thisLinda

Reputation: 65

My app threw the same error yesterday. I spent hours reading questions/answers here on SO and trying some. What has worked for me is this:

https://github.com/ChainSafe/web3.js#troubleshooting-and-known-issues

Upvotes: 0

secret
secret

Reputation: 235

Create React App just released v5 which now implements Webpack v5. This is going to fully break many libraries which includes web3 as the required Node core library polyfills will be missing.

To resolve this quickly you can change this in your package.json:

"react-scripts": "^5.0.0"

To this

"react-scripts": "4.0.3"

After this:

rm -r node_modules

rm package-lock.json

npm install

Upvotes: 18

Letton
Letton

Reputation: 367

You need React => v17 React scripts=> v5 webpack => v5

To Fix The Problem

1) Install

"fs": "^2.0.0",  // npm i fs
"assert": "^2.0.0",  // npm i assert
"https-browserify": "^1.0.0", // npm i https-browserify
"os": "^0.1.2", // npm i os
"os-browserify": "^0.3.0", // npm i os-browserify
"react-app-rewired": "^2.1.9", //npm i react-app-rewired
"stream-browserify": "^3.0.0", // stream-browserify
"stream-http": "^3.2.0", //stream-http

2) Creating config-overrides.js in root directory Image

3) Add configs to config-overrides.js

const webpack = require('webpack');
module.exports = function override(config, env) {
    config.resolve.fallback = {
        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'),
    };
    config.plugins.push(
        new webpack.ProvidePlugin({
            process: 'process/browser',
            Buffer: ['buffer', 'Buffer'],
        }),
    );

    return config;
}

3) Change packages.json

"scripts": {
  "start": "react-app-rewired start",
  "build": "react-app-rewired build",
  "test": "react-app-rewired test",
  "eject": "react-app-rewired eject"
}

Problem solved :)

Upvotes: 25

Vijay Vasan
Vijay Vasan

Reputation: 59

you want to used in

const nodeExternals = require('webpack-node-externals');

add in webpack.config.js

target: "node",
devtool: "source-map",
externals: [nodeExternals()],

Upvotes: 4

Related Questions