react-pdf: Fail to compile: Can't resolve 'stream'

I recently upgraded to webpack 5.65.0. @react-pdf/renderer@2.0.21 was working fine before I upgraded. Now ‘npm start’ gives me this error:

PS D:\Projects\NewEcommerce\EcommerceUI\ClientApp> npm start

> ecommerceui@0.1.0 start
> rimraf ./build && react-scripts start
Starting the development server...
Failed to compile.

Module not found: Error: Can't resolve 'stream' in 'D:\Projects\NewEcommerce\EcommerceUI\ClientApp\node_modules\@react-pdf\pdfkit\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: { "stream": require.resolve("stream-browserify") }'
        - install 'stream-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
        resolve.fallback: { "stream": false }
[...]

Desktop:

  • OS: Windows
  • Browser firefox

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 29
  • Comments: 33

Most upvoted comments

@jeetiss is there a solution for folks using unejected create-react-app? There’s no webpack file for me to modify. 😦

Yes, this can be accomplished using the craco package.

Install craco and additional packages specified in the updated react-pdf docs (thanks @jeetiss 🙏🏻):

yarn add process browserify-zlib stream-browserify util buffer assert @craco/craco

Change the scripts section in package.json as below:

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

Finally, create a new file in the root of the project craco.config.js with these contents:

const webpack = require("webpack");

module.exports = {
  webpack: {
    configure: {
      resolve: {
        fallback: {
          process: require.resolve("process/browser"),
          zlib: require.resolve("browserify-zlib"),
          stream: require.resolve("stream-browserify"),
          util: require.resolve("util"),
          buffer: require.resolve("buffer"),
          asset: require.resolve("assert"),
        },
      },
      plugins: [
        new webpack.ProvidePlugin({
          Buffer: ["buffer", "Buffer"],
          process: "process/browser",
        }),
      ],
    },
  },
};

This resolved the problem for me.

I’m wondering if is there any plans to fix the package instead of adding other packages as a workaround to make it work?

@jeetiss is there a solution for folks using unejected create-react-app? There’s no webpack file for me to modify. 😦

hey folks, I added setup instructions for webpack 5

https://github.com/diegomura/react-pdf#webpack-5

Could you please confirm that it helps?

Hello Folks!, For does of you who are using create-react-app and have installed the plugins as instructed Here. If you attempts to add the webpack config to your project root dir it will not work why? this because react js does not read that file unless you want to write an override file to webpack.

But never the less they is a work around to this all you have to do is edit the webpack configuration file that react-scripts uses in compiling the react app. with the configuration provided below:

yarn add process browserify-zlib stream-browserify util buffer assert

const webpack = require("webpack");

module.exports = {
  /* ... */

  resolve: {
    fallback: {
      process: require.resolve("process/browser"),
      zlib: require.resolve("browserify-zlib"),
      stream: require.resolve("stream-browserify"),
      util: require.resolve("util"),
      buffer: require.resolve("buffer"),
      asset: require.resolve("assert"),
    }
  },
  plugins: [
    new webpack.ProvidePlugin({
      Buffer: ["buffer", "Buffer"],
      process: "process/browser",
    }),
  ]

  /* ... */
}

Copy the plugins code and as past it to react-scripts in your node_modules file located at: node_modules\react-scripts\config\webpack.config.js

now for the fallback locate the resolve object and past the fallback provided here at the end.

***Note Make sure to install the files first before attempting the settings.

Hope this help cause it solve my problem.

add "stream": "npm:stream-browserify@^3.0.0", to your package.json or

npm i stream@npm:stream-browserify

@jeetiss is there a solution for folks using unejected create-react-app? There’s no webpack file for me to modify. 😦

Yes, this can be accomplished using the craco package.

Install craco and additional packages specified in the updated react-pdf docs (thanks @jeetiss 🙏🏻):

yarn add process browserify-zlib stream-browserify util buffer assert @craco/craco

Change the scripts section in package.json as below:

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

Finally, create a new file in the root of the project craco.config.js with these contents:

const webpack = require("webpack");

module.exports = {
  webpack: {
    configure: {
      resolve: {
        fallback: {
          process: require.resolve("process/browser"),
          zlib: require.resolve("browserify-zlib"),
          stream: require.resolve("stream-browserify"),
          util: require.resolve("util"),
          buffer: require.resolve("buffer"),
          asset: require.resolve("assert"),
        },
      },
      plugins: [
        new webpack.ProvidePlugin({
          Buffer: ["buffer", "Buffer"],
          process: "process/browser",
        }),
      ],
    },
  },
};

This resolved the problem for me. This worked for me too

I’m wondering if is there any plans to fix the package instead of adding other packages as a workaround to make it work?

Its almost 9 months and no fix released yet on npm ? 9 months are very long for this library which is used by millions.

craco based solution works but it should have been stop-gap solution.

I don’t think this is an error that react-pdf is throwing, it’s an error that webpack is throwing, due to webpack v5 having removed node.js polyfills: https://webpack.js.org/blog/2020-10-10-webpack-5-release/#automatic-nodejs-polyfills-removed.

Thus for people using create-react-app, since it uses webpack, you will get this error unless you apply one of the solutions like craco or react-app-rewired.

Here’s the issue for create-react-app; it contains additional information and opinions from developers: https://github.com/facebook/create-react-app/issues/11756

I’m thinking about trying a newer build tool like Vite which does the work of webpack and includes quick-start templates like CRA: yarn create vite my-react-app --template react-ts

@gmartinu I am not have any luck implementing you fix for Webpack 5.

I have only installed the npms and added your recommendations to my webpack.config.js. When I try running I get this:

Starting the development server...

D:\Projects\NewEcommerce\EcommerceUI\ClientApp\node_modules\webpack\lib\NormalModule.js:1349
                hash.update(this.buildInfo.hash);
                                           ^

TypeError: Cannot read properties of undefined (reading 'hash')
    at NormalModule.updateHash (D:\Projects\NewEcommerce\EcommerceUI\ClientApp\node_modules\webpack\lib\NormalModule.js:1349:30)
    at Compilation._createModuleHash (D:\Projects\NewEcommerce\EcommerceUI\ClientApp\node_modules\webpack\lib\Compilation.js:3891:10)
    at Compilation.createModuleHashes (D:\Projects\NewEcommerce\EcommerceUI\ClientApp\node_modules\webpack\lib\Compilation.js:3858:25)
    at D:\Projects\NewEcommerce\EcommerceUI\ClientApp\node_modules\webpack\lib\Compilation.js:3007:11
    at Hook.eval [as callAsync] (eval at create (D:\Projects\NewEcommerce\EcommerceUI\ClientApp\node_modules\tapable\lib\HookCodeFactory.js:33:10), <anonymous>:6:1)
    at Hook.CALL_ASYNC_DELEGATE [as _callAsync] (D:\Projects\NewEcommerce\EcommerceUI\ClientApp\node_modules\tapable\lib\Hook.js:18:14)
    at D:\Projects\NewEcommerce\EcommerceUI\ClientApp\node_modules\webpack\lib\Compilation.js:2963:36
    at Hook.eval [as callAsync] (eval at create (D:\Projects\NewEcommerce\EcommerceUI\ClientApp\node_modules\tapable\lib\HookCodeFactory.js:33:10), <anonymous>:6:1)
    at Hook.CALL_ASYNC_DELEGATE [as _callAsync] (D:\Projects\NewEcommerce\EcommerceUI\ClientApp\node_modules\tapable\lib\Hook.js:18:14)
    at Compilation.seal (D:\Projects\NewEcommerce\EcommerceUI\ClientApp\node_modules\webpack\lib\Compilation.js:2954:27)

I have all the reactpdf references commented out in my code, I am just trying to get the additions loaded properly. I have attached a zip of my webpack.config.js.

webpack.config.zip

@michaelmarziani Yes, this can be accomplished using the craco package.

Getting a Invalid configuration object when running with the craco solution for CRA. Any ideas?

Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.

  • configuration.resolve has an unknown property ‘fallback’. These properties are valid: object { alias?, aliasFields?, cachePredicate?, cacheWithContext?, concord?, descriptionFiles?, enforceExtension?, enforceModuleExtension?, extensions?, fileSystem?, mainFields?, mainFiles?, moduleExtensions?, modules?, plugins?, resolver?, roots?, symlinks?, unsafeCache?, useSyncFileSystemCalls? } -> Options for the resolver

I’m wondering if is there any plans to fix the package instead of adding other packages as a workaround to make it work?

Its almost 9 months and no fix released yet on npm ? 9 months are very long for this library which is used by millions.

craco based solution works but it should have been stop-gap solution.

With craco and the configuration above I’m getting this error:

Module not found: Error: Can't resolve 'process/browser' in '/home/ctrlmaniac/node_modules/uvu/node_modules/kleur'
Did you mean 'browser.js'?
BREAKING CHANGE: The request 'process/browser' failed to resolve only because it was resolved as fully specified
(probably because the origin is strict EcmaScript Module, e. g. a module with javascript mimetype, a '*.mjs' file, or a '*.js' file where the package.json contains '"type": "module"').
The extension in the request is mandatory for it to be fully specified.
Add the extension to the request.

how to solve it?

hey folks, for those who still have “Module not found: Error: Can’t resolve ‘stream’” error (stream and zlib) even after installing the shims and configuring them. It’s probably because you set up aliases in your Webpack config, I fixed the problem by adding aliases for stream and zlib

webpack: {
    alias: {
      ...resolvedAliases,
      zlib: require.resolve("browserify-zlib"),
      stream: require.resolve("stream-browserify")
    },
    resolve: {
      fallback: {
        module: "empty",
        dgram: "empty",
        dns: "mock",
        fs: "empty",
        http2: "empty",
        net: "empty",
        tls: "empty",
        child_process: "empty",
        process: require.resolve("process/browser"),
        zlib: require.resolve("browserify-zlib"),
        stream: require.resolve("stream-browserify"),
        util: require.resolve("util"),
        buffer: require.resolve("buffer"),
        asset: require.resolve("assert")
      }
    },
    plugins: [
      new BundleAnalyzerPlugin(),
      new webpack.ProvidePlugin({
        Buffer: ["buffer", "Buffer"],
        process: "process/browser"
      })
    ]
  }

hey folks, I added setup instructions for webpack 5

https://github.com/diegomura/react-pdf#webpack-5

Could you please confirm that it helps?

Great answer, worked like a charm

@RomanTurner Hi Roman, the only thing in the error that stands out to me is configuration.resolve. In my craco.config.js, the object that contains resolve is configure.

I posted a start to finish example using CRA and react-pdf to stackoverflow: https://stackoverflow.com/a/70441023/2193573

I’d offer that if you follow that and get to a successful build, perhaps you can compare the config with that of your project and see what might be wrong.

Good luck!