fcl-js: FCL does not bundle with create-react-app on node v16 and latest Webpack

Instructions

Please fill out the template below to the best of your ability and include a label indicating which tool/service you were working with when you encountered the problem.

Problem

When following the FCL quickstart tutorial https://docs.onflow.org/fcl/tutorials/flow-app-quickstart/ , on Node 16 Webpack throws an error (see below)

Steps to Reproduce

Node version: v16.13.1

Follow first steps of the FCL quickstart tutorial above, namely:

npx create-react-app flow-app
cd flow-app
npm install @onflow/fcl --save
# ... (create config.js with appropriate contents)
# ... (update App.js to contain all relevant quickstart code)
npm run start

Will result in:

ERROR in ./node_modules/@improbable-eng/grpc-web-node-http-transport/lib/index.js 8:11-26

Module not found: Error: Can't resolve 'http' in '/Users/mac/Desktop/flow/flow-dapp/node_modules/@improbable-eng/grpc-web-node-http-transport/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: { "http": require.resolve("stream-http") }'
    - install 'stream-http'
If you don't want to include a polyfill, you can use an empty module like this:
    resolve.fallback: { "http": false }

Acceptance Criteria

Make FCL bundleable with new versions of webpack. This is also somewhat connected to #711 , as FCL is quite flaky with bundlers in general, as it doesn’t have proper ESM support. See https://github.com/samatechtw/onflow-fcl-esm for example of fix (this is working correctly for Vite)

Context

Not able to reproduce FCL quickstart tutorial

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 2
  • Comments: 17 (4 by maintainers)

Most upvoted comments

Great work @muttoni

Javascript and bundlers are unfortunately big mess, maybe FCL should provide browserized modules in the future. ( I don’t see much problem using polyfills also on node side )

+1 on NextJS, as it also sets the foundations for a more complete application. I’ve taken a stab at porting it to Next.js here: https://github.com/onflow/fcl-js/pull/953

I kept the approach/philosophy the same, but I also took the opportunity to link to some ready to go samples at the top for people just wanted to clone and go.

Another alternative would be to ditch CRA and use NextJS instead. There are no downsides when switching imo, and the upside is you don’t have to deal with Webpack 👌🏼

Hey folks, was following the tutorial on my own time and found this issue too. Here’s how I fixed it:

  • run npm run eject => input y when prompted
  • install the following dependencies npm i -D url stream-http buffer process https-browserify
  • in ./config/webpack.config.js add the following in the resolve object
     fallback: {
          "http": require.resolve("stream-http"),
          "https": require.resolve('https-browserify'),
          "buffer": require.resolve('buffer'),
          "url": require.resolve("url/"),
        },
    
  • add the following in the plugins object *make sure you don’t put it in one of the nested plugins objects
     new webpack.ProvidePlugin({
              process: 'process/browser',
              Buffer: ['buffer', 'Buffer'],
          }),
    

Really weird for webpack to implement such a breaking change. I’d imagine at least create-react-app to include some bloatware that more advanced users can remove if needed.

Cheers folks

I found a temporary workaround by changing package.json’s line react-scripts from 5.x to 4.0.3 Example

"react-scripts": "4.0.3",

This is a temporary workaround as it downgrades many things, but the polyfill issue is alleviated.

It doesn’t work for me. I changed that dependency and rerun and got exactly the same error. Did you do anything else to make it work?

After changing the react scripts version, you need to delete node_modules and package-lock.json

rm -rf node_modules package-lock.json

Now rerun: npm install.