Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v5 used to include polyfills for node.js core modules by default #11756

Open
damozhang opened this issue Dec 15, 2021 · 270 comments
Open

v5 used to include polyfills for node.js core modules by default #11756

damozhang opened this issue Dec 15, 2021 · 270 comments

Comments

@damozhang
Copy link

damozhang commented Dec 15, 2021

Describe the bug

Compiled with problems

Did you try recovering your dependencies?

yarn --version
1.22.15

Which terms did you search for in User Guide?

react-scripts 5 webpack Module not found: Error: Can't resolve 'fs'

Environment

npx create-react-app --info

Environment Info:

  current version of create-react-app: 5.0.0
  running from /Users/xxx/.config/yarn/global/node_modules/create-react-app

  System:
    OS: macOS 12.0.1
    CPU: (8) x64 Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz
  Binaries:
    Node: 16.13.0 - /usr/local/Cellar/node@16/16.13.0/bin/node
    Yarn: 1.22.15 - /usr/local/bin/yarn
    npm: 8.1.0 - /usr/local/Cellar/node@16/16.13.0/bin/npm
  Browsers:
    Chrome: 96.0.4664.93
    Edge: Not Found
    Firefox: 94.0.1
    Safari: 15.1
  npmPackages:
    react:  17.0.2 
    react-dom:  17.0.2 
    react-scripts:  5.0.0 
  npmGlobalPackages:
    create-react-app: Not Found

Steps to reproduce

In a project with react-scripts v5.0.0

  1. yarn add -D dotenv
  2. yarn start

Expected behavior

Actual behavior

ERROR in ../../node_modules/dotenv/lib/main.js 24:11-24
Module not found: Error: Can't resolve 'fs' in '../node_modules/dotenv/lib'
 @ ./src/config.ts 5:0-28 8:0-13
 @ ./src/index.tsx 17:0-66 27:19-27 29:23-43 30:23-43 34:35-60

ERROR in ../../node_modules/dotenv/lib/main.js 26:13-28
Module not found: Error: Can't resolve 'path' in '../node_modules/dotenv/lib'

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: { "path": require.resolve("path-browserify") }'
	- install 'path-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
	resolve.fallback: { "path": false }
 @ ./src/config.ts 5:0-28 8:0-13
 @ ./src/index.tsx 17:0-66 27:19-27 29:23-43 30:23-43 34:35-60

ERROR in ../../node_modules/dotenv/lib/main.js 28:11-24
Module not found: Error: Can't resolve 'os' in '../node_modules/dotenv/lib'

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: { "os": require.resolve("os-browserify/browser") }'
	- install 'os-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
	resolve.fallback: { "os": false }
 @ ./src/config.ts 5:0-28 8:0-13
 @ ./src/index.tsx 17:0-66 27:19-27 29:23-43 30:23-43 34:35-60

3 errors have detailed information that is not shown.
Use 'stats.errorDetails: true' resp. '--stats-error-details' to show it.

Some useful comments:

@arjshiv
Copy link

arjshiv commented Dec 15, 2021

I have the same issue as well

@FeiFanLiang
Copy link

me too

@raix
Copy link
Contributor

raix commented Dec 15, 2021

Webpack 5 no longer shims node builtin packages. Its a breaking change.

@zfarhad
Copy link

zfarhad commented Dec 15, 2021

I try to upgrade from v4.0.3 to 5.0.0 and It raise up the same error

Compiled with problems:

ERROR in ./src/App.js 1:40-111

Module not found: Error: You attempted to import /home/xxx/web/node_modules/react-refresh/runtime.js which falls outside of the project src/ directory. Relative imports outside of src/ are not supported.
You can either move it inside src/, or add a symlink to it from project's node_modules/.

@AdnanDervisevic
Copy link

Webpack 5 no longer shims node builtin packages. Its a breaking change.

Are we meant to eject for every app that relies on node builtin packages? Won't that be most production apps, since you will invariably import a node module that relies on this functionality

@raix
Copy link
Contributor

raix commented Dec 15, 2021

My personal view:
I personally consider it bad practice to include code in the front-end that was ment for back-end usage.
From my experience:
I've seen developers of any experienced try adding back-end npm packages on the front-end.

In Npm there is no clear difference to help out developers, it's "Node Packages" not "Browser Packages"

Package maintainers should ideally build node or browser specific bundles.

Again this is my personal view I support the move in Webpack, I'll of course bring it up in the maintainer group.

(Also see the release notes regarding webpack 5 - there's a note regarding this breaking change for further details)

For now it would be helpful to collect examples of front-end packages suffering from this issue.
(The examples would help us reevaluate the decision)

@sean-daley
Copy link

sean-daley commented Dec 15, 2021

Our two main usages are:

  1. zlib
  2. crypto

Our back-end compresses some of its data to optimize storage as well as network transfer. Our UI then uses zlib to uncompress it.
Our UI can also login using OAuth and it uses the crypto randomBytes and createHash methods to generate data for that authorization

@dylantf
Copy link

dylantf commented Dec 15, 2021

Webpack has some output about providing a fallback resolution, what's the correct way to supply that since we don't have access to the actual webpack config?

@jrr
Copy link
Contributor

jrr commented Dec 15, 2021

To toss in another example, the v5 upgrade showed me that the libraries for AWS Cognito use url:

> yarn build
Creating an optimized production build...
Failed to compile.

Module not found: Error: Can't resolve 'url' in '/path/to/app/.yarn/cache/@aws-amplify-core-npm-4.3.10-e9277c22ab-77b7fe62d8.zip/node_modules/@aws-amplify/core/lib-esm'
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: { "url": require.resolve("url/") }'
	- install 'url'
If you don't want to include a polyfill, you can use an empty module like this:
	resolve.fallback: { "url": false }
> 

If you were a direct user of webpack v4, upgrading to v5, you have a few options:

  1. stay on v4
  2. remove usage of polyfilled modules
  3. add polyfills

If I were in this situation, I'd be taking option 3. But as I understand it, that's not available today with non-ejected CRA.

It'd be nice if Webpack 5 had a single switch to flip, to restore v4's polyfill behavior. Then CRA could expose just that one switch. But there isn't: Webpack's migration guidance is to manually add polyfills to your webpack config.

https://webpack.js.org/blog/2020-10-10-webpack-5-release/#automatic-nodejs-polyfills-removed

Here are the polyfills that were formerly provided by webpack (note that the project is deprecated): https://github.com/webpack/node-libs-browser

..so what should CRA do?

@raix
Copy link
Contributor

raix commented Dec 15, 2021

I've added a pr to gather feedback #11764

@BiancaArtola
Copy link

Same issue here. is there some documentation that we can follow for doing this migration?

@LukeNotable
Copy link

I'm not sure it's entirely a polyfill issue. I'm getting the Can't resolve 'fs' due to Handlebars, which (IIRC) should have been prevented by its browser setting in package.json.

@raix
Copy link
Contributor

raix commented Dec 15, 2021

@LukeNotable thanks, interesting finding - I'll convert #11764 to a draft for now - would be great if it's an issue in the webpack config not resolving main fields correctly ref config: https://webpack.js.org/configuration/resolve/#resolvemainfields - will try to replicate

@jasonleehodges
Copy link

@zfarhad I had the same issue. Found out it was because I had Storybook as a dependency and it was using Webpack 4. Upgrading Storybook to use their new alpha version that supports Webpack 5 fixed me. So I would say, make sure none of your dependencies are using a conflicting version of webpack.

@raix
Copy link
Contributor

raix commented Dec 16, 2021

@LukeNotable when importing 'handlebars/runtime' webpack seem to resolve correctly but if importing 'handlebars' it resolves to 'lib/index.js'

'''
"browser": {
".": "./dist/cjs/handlebars.js",
"./runtime": "./dist/cjs/handlebars.runtime.js"
},
'''
I'll take a second look tomorrow, could be a config issue in CRA

@German919
Copy link

ERROR in Plugin "react" was conflicted between "package.json » eslint-config-react-app.
Estoy teniedo este error y no encuentro como solucionarlo..

@jordanwilking
Copy link

Fwiw, seeing this for a package trying to use assert and stream-browserify.

@raix
Copy link
Contributor

raix commented Dec 17, 2021

Webpack 5 and CRA v5 don't add fallbacks for nodejs modules any more, it's a breaking change - dotenv should not be added in the browser code related issues closed in dotenv repo

Migration steps from v4 to v5:

A: Go to the Npm or Github readme for the package you are trying to use and see if the package is meant to run in the browser

  • If no - Then remove the package and find an alternative package better suited

B: Search in the package Github issues for "browser" and include closed issues, please. Example for DotEnv repo

  • If the maintainers multiple times state that the package is NOT meant for usage in the front-end and close the issues - Then remove the package and find an alternative package better suited

C: If the package should support the browser - then open an issue here in the CRA repo and we'll look into it - here to help!

An example: @LukeNotable raised an issue - we've confirmed that as an issue, debugged and opened an issue in the Webpack repository.
Please note a very important detail regarding the handlebars package:

  1. It provides a main field "browser" and bundle files specific to the browser
  2. import "handlebars/runtime" resolves in the browser code
  3. import "handlebars" resolves NodeJS version... Adding fallbacks for nodejs builtins would hide this issue

We have opened an issue in Webpack webpack/webpack#15007

Sorry for the breaking change, but we are trying to keep you safe - we are considering better error message / documentation etc.

Kind regards Morten

@raix raix changed the title Compiled with problems after upgrade to 5.0.0 v5 used to include polyfills for node.js core modules by default Dec 17, 2021
@raix raix pinned this issue Dec 17, 2021
@raix raix unpinned this issue Dec 17, 2021
@lanwin
Copy link

lanwin commented Dec 17, 2021

Uh my guess is that this means a lot people can not upgrade to v5 for a long time. In example our own deps report 50 errors cause nodes assert ist used in various deps.

@dylantf
Copy link

dylantf commented Dec 17, 2021

"Then remove the package and find an alternative package better suited" is a great strategy when you have an unlimited budget, but in many cases these packages work just fine in the browser with a polyfill, and sometimes packages in the JS ecosystem go unmaintained and there aren't any good alternatives. If Webpack 5 has an option to include the polyfills, but CRA does not, are we just expected to immediately eject upon upgrading to edit the webpack config, or just stay on CRA 4?

@raix
Copy link
Contributor

raix commented Dec 17, 2021

We need to make sure that we are fixing the root cause and not the symptom - like with the handlebars example above e.g. There might be an issue in Webpack webpack/webpack#15007 - let's evaluate if that fixes most of the errors.

To repeat #11756 (comment) we a considering adding an escape hatch and document why not to use it #11764

Again - if you are using packages not meant for the browser - and the maintainers of those packages keep closing issues for browser support and state that the package is not meant for the browser, then it's likely a good idea to find another package that supports the browser.

For more details on what nodejs builtin modules are see the nodejs api docs

@ljharb
Copy link

ljharb commented Jan 27, 2023

@damozhang no, issues should only be closed when they're fixed, not just because they're ignored.

@reviewher
Copy link

@damozhang other people are finding this issue and commenting. That probably means it is still a pain point in 2023. The best thing you can do is keep the issue open, add some links or mention alternatives in the original post (for example, how did you migrate from CRA to NextJS?), and unsubscribe from the thread if you find the emails annoying.

@tony123S
Copy link

we are fixing the root cause and not the sympto

If I create a React app without using create-react-app, what should change in package.json?

Here my scripts

 "scripts": {
    "start": "webpack-dev-server .",
    "build": "webpack ."
  },

@BearCooder
Copy link

Guys better prepare to switch over to something else than Create React App instead of complaining that your web3 crypto dapp is not working anymore.
reactjs/react.dev#5487

@arbitar
Copy link

arbitar commented Feb 5, 2023

reactjs/reactjs.org#5487

An extremely welcome change. Directing newbies to CRA is creating more problems for them than it's solving. Let's get this junk out of the way on the official docs - really bad for such a major project to be funneling all its new users through broken abandonware.

@sandtreader
Copy link

Found a pretty simple workaround that's been working for my projects without having to eject or use react-app-rewired/craco.

So instead of having Webpack polyfil these missing node code dependencies, just have NPM install the polyfils as the named packages directly. You can specify the versions too. Example:

"devDependencies": {
  "buffer": "npm:buffer@6.0.3",
  "crypto": "npm:crypto-browserify@3.12.0",
  "stream": "npm:stream-browserify@3.0.0",
  "util": "npm:util@0.12.5",
}

This answer needs more attention! I had the exact same problem trying to use xml-js in a CRA app. xml-js uses sax, which wants node 'stream', so I was getting the same kind of webpack v5 errors. Was looking down the barrel of ejecting or using craco and hacking webpack configs... But thanks to @VigM-Figure, just adding:

"stream": "npm:stream-browserify@3.0.0",

to my package.json "dependencies" solved it completely, and will do fine until some sanity returns :-)

@tony-garcia
Copy link

tony-garcia commented Feb 8, 2023

I switched to Vite.js, which builds much faster than CRA and has a built-in way to configure for enabling node polyfills

@GavinThomas1192
Copy link

GavinThomas1192 commented Feb 9, 2023

I finally switched to Vite after commenting/following this thread for months. Vite is so much faster, it cut our production pipelines build times in half. Development reloads 2 seconds faster every refresh.
I wish I would have switched sooner. I also was using crypto-js.
Some things of note if you switch, you have to convert all your .js files that have jsx to .jsx.
find ./src -type f -name '*.js' -not -name '*.jsx' -not -name '*.ejs' -exec bash -c 'grep -l "</\|/>" $0' {} \; -exec bash -c 'mv "$0" "${0%.js}.jsx"' {} \;
I used this article to switch https://cathalmacdonnacha.com/migrating-from-create-react-app-cra-to-vite.
My Vite config

import react from '@vitejs/plugin-react';
import viteTsconfigPaths from 'vite-tsconfig-paths';
import svgrPlugin from 'vite-plugin-svgr';

export default defineConfig({
  server: {
    port: 3001,
  },
  plugins: [react(), viteTsconfigPaths(), svgrPlugin()],
  esbuild: {
    loader: 'tsx',
  },
  optimizeDeps: {
    esbuildOptions: {
      loader: {
        '.js': 'jsx',
        '.ts': 'tsx',
      },
    },
  },
  css: {
    preprocessorOptions: {
      less: {
        javascriptEnabled: true,
      },
    },
  },
  resolve: {
    alias: [
      { find: /^~/, replacement: '' },
    ],
  },
  build: {
    outDir: 'build',
  },
});

@StrawberryChocolateFudge

I'm using Ionic Framework to develop for Android, it uses webpack v5 with React, I have the same issue.

This solution posted here works:

"devDependencies": { "buffer": "npm:buffer@6.0.3", "crypto": "npm:crypto-browserify@3.12.0", "stream": "npm:stream-browserify@3.0.0", "util": "npm:util@0.12.5", }

except I have a runtime error because of process and using this above solution with the process dependency from NPM does not fix the issue at all and ejecting to try to configure it like that just breaks my build.

@tiennguyen1293
Copy link

I'm facing this issue


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: { "path": require.resolve("path-browserify") }'
	- install 'path-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
	resolve.fallback: { "path": false }
ERROR in ./src/styles.scss (./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[1].oneOf[7].use[1]!./node_modules/react-scripts/node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[1].oneOf[7].use[2]!./node_modules/resolve-url-loader/index.js??ruleSet[1].rules[1].oneOf[7].use[3]!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[1].oneOf[7].use[4]!./src/styles.scss)
Module build failed (from ./node_modules/sass-loader/dist/cjs.js):
SassError: File to import not found or unreadable: ./styles/colors.
        on line 1 of src/styles/_normalize.scss
        from line 1 of src/styles.scss
>> @import './styles/colors';

@mmsaki
Copy link

mmsaki commented Mar 13, 2023

I have the same issue with Angular

JLyons1985 pushed a commit to dod-advana/gamechanger-web that referenced this issue Mar 16, 2023
mcauley-penney added a commit to Empyrean-Capstone/Empyrean that referenced this issue Mar 16, 2023
When registering a user, hash their password
before committing it to the database. When
logging a user in, hash their password before
comparing it against the database.

Note: Using bcryptjs currently gives compilation
	  warnings. It is not an issue arising from
	  our code. I've used a hack to package.json,
	  found at the link below, as a means of
	  quieting it until the issue is resolved.

facebook/create-react-app#11756 (comment)
@brownieboy
Copy link

brownieboy commented Mar 19, 2023

So instead of having Webpack polyfil these missing node code dependencies, just have NPM install the polyfils as the named packages directly. You can specify the versions too. Example:

"devDependencies": {
  "buffer": "npm:buffer@6.0.3",
  "crypto": "npm:crypto-browserify@3.12.0",
  "stream": "npm:stream-browserify@3.0.0",
  "util": "npm:util@0.12.5",
}

Works for me, although I needed some extra ones for http, https and zlib:

"devDependencies": {
    "buffer": "npm:buffer@^6.0.3",
    "crypto": "npm:crypto-browserify@^3.12.0",
    "http": "npm:stream-http@^3.2.0",
    "https": "npm:https-browserify@^1.0.0",
    "stream": "npm:stream-browserify@^3.0.0",
    "util": "npm:util@^0.12.5",
    "zlib": "npm:browserify-zlib@^0.2.0"
}

Is the npm: syntax needed though? This appears to just specify that the package comes from npmjs, but it will do that anyway, right?

Update
Looks like that npm: syntax is needed. When I removed it and then ran yarn install, it threw an error. I didn't try with npm itself.

@haneenmahd
Copy link

I happened to face this issue while using jsonwebtoken for my react app.

@Neurothustra
Copy link

so CRA is effectively broken? And the dev team doesn't care?

@haneenmahd
Copy link

The cause of this issue is when you use a module that was meant for Node for the Browser. With Webpack 5, they stopped bundling backend modules for web. So, I think the only problem is that you're using a module that wasn't supported for web. I think in my case it was using jsonwebtoken which relied on the polyfill of std Node modules. I switch to using jose which supports the browser.

@ljharb
Copy link

ljharb commented Apr 11, 2023

@haneenmahd everything that with a working bundler that includes core module polyfills, supports the browser. webpack 5 simply decided to stop being a working node module bundler.

@baughmann
Copy link

Are your guys bosses living in a VR world already? How about you tell them to take off the goggles and fix this crap.

@alome007
Copy link

Screenshot 2023-04-18 at 23 03 56

@ArinCantCode
Copy link

for react-native errors:

first install react-native-web

and add

'react-native': require.resolve('react-native-web')

to your config-overrides.js

@Dronom
Copy link

Dronom commented Jun 12, 2023

I have the same issue with react-dev-utils:
BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default. [0] This is no longer the case. Verify if you need this module and configure a polyfill for it. [0] [0] If you want to include a polyfill, you need to: [0] - add a fallback 'resolve.fallback: { "url": require.resolve("url/") }' [0] - install 'url' [0] If you don't want to include a polyfill, you can use an empty module like this: [0] resolve.fallback: { "url": false }

P.S. Adding the "url" directly to your own package.json will solve the problem.

@michaelmarziani
Copy link

I think the salient point for any who come across this thread is that the React.js team no longer recommends CRA in the updated React docs. Here are the recommended frameworks for new react projects:
https://react.dev/learn/start-a-new-react-project

Good luck!

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

Successfully merging a pull request may close this issue.