4

Help me install the react-pdf package (https://github.com/diegomura/react-pdf) on create react app. I can't make changes to webpack.config. I do it according to the instructions I found here from the user River Twilight: How to update webpack config for a react project created using create-react-app?

According to the instructions of installing react-pdf

  1. I run npm install process browserify-zlib stream-browserify util buffer assert
  2. Created config-override.js in project root folder
  3. Next you need to insert the following lines into the config:

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",
    }),
  ]

  /* ... */
}

But a) webstorm swears, b) the project is not started by the "start": "react-app-rewired start".

Errors that I get without changing the config:

Compiled with problems:X

ERROR in ./node_modules/@react-pdf/pdfkit/lib/pdfkit.browser.es.js 2:0-28

Module not found: Error: Can't resolve 'stream' in 'C:\Users\schek\Desktop\react\snitch\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 }


ERROR in ./node_modules/@react-pdf/pdfkit/lib/pdfkit.browser.es.js 4:0-24

Module not found: Error: Can't resolve 'zlib' in 'C:\Users\schek\Desktop\react\snitch\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: { "zlib": require.resolve("browserify-zlib") }'
    - install 'browserify-zlib'
If you don't want to include a polyfill, you can use an empty module like this:
    resolve.fallback: { "zlib": false }


ERROR in ./node_modules/@react-pdf/png-js/lib/png-js.browser.es.js 1:0-24

Module not found: Error: Can't resolve 'zlib' in 'C:\Users\schek\Desktop\react\snitch\node_modules\@react-pdf\png-js\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: { "zlib": require.resolve("browserify-zlib") }'
    - install 'browserify-zlib'
If you don't want to include a polyfill, you can use an empty module like this:
    resolve.fallback: { "zlib": false }


ERROR in ./node_modules/blob-stream/index.js 1:21-47

Module not found: Error: Can't resolve 'stream' in 'C:\Users\schek\Desktop\react\snitch\node_modules\blob-stream'

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 }


ERROR in ./node_modules/restructure/src/EncodeStream.js 23:11-28

Module not found: Error: Can't resolve 'stream' in 'C:\Users\schek\Desktop\react\snitch\node_modules\restructure\src'

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 }
Schekhovtsov
  • 101
  • 2
  • 10

4 Answers4

5

These errors seems to have happened due to react-scripts v5. Took me a day to figure out a solution while using react-router v5. But it seems the best approach for now is to stay on, or revert back to v4.0.3 until v5 adds back support for node built-ins #11764 is merged and released.

This issue on Github might help.

Mehrbanian
  • 86
  • 3
3

You can use rewire to change the settings of webpack config without ejecting.

npm i rewire

I put two scripts (start.js and build.js) in a scripts folder in root directory (i.e. outside src). Then in package.json change the start and build scripts to use those.

"start": "node scripts/start.js",
"build": "node scripts/build.js",

start.js:

const rewire = require('rewire');
const webpack = require('webpack');
const defaults = rewire('react-scripts/scripts/start.js');
const webpackConfig = require('react-scripts/config/webpack.config');

//In order to override the webpack configuration without ejecting the create-react-app
defaults.__set__('configFactory', (webpackEnv) => {
  let config = webpackConfig(webpackEnv);

  //Customize the webpack configuration here.
  config.resolve.fallback = {
    ...config.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'),
  };

  config.plugins = [
    ...config.plugins,
    new webpack.ProvidePlugin({
      Buffer: ['buffer', 'Buffer'],
      process: 'process/browser',
    }),
  ];

  return config;
});

build.js:

const rewire = require('rewire');
const webpack = require('webpack');
const defaults = rewire('react-scripts/scripts/build.js');

//In order to override the webpack configuration without ejecting the create-react-app
const config = defaults.__get__('config');

//Customize the webpack configuration here.
config.resolve.fallback = {
  ...config.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'),
};

config.plugins = [
  ...config.plugins,
  new webpack.ProvidePlugin({
    Buffer: ['buffer', 'Buffer'],
    process: 'process/browser',
  }),
];

This is a combination of this post and the readme you already refered to.

...and ofcourse you also need the once you already had:

npm install process browserify-zlib stream-browserify util buffer assert
yoneriks
  • 31
  • 1
1

Maybe my answer is a bit too late, but for those who have browsed and tried many different solutions on this but still not working, this is the one that works for me.

The problem that I'm encountering is using react-pdf with react-scripts (version 5.0.1). One possible solution I found is to modify the webpack config file. However, I don't want to eject CRA for this, so this is the way I do:

  1. Install craco and some additional packages:
yarn add process browserify-zlib stream-browserify util buffer assert @craco/craco
  1. Change the scripts section inside the package.json file as below:
"scripts": {
  "start": "craco start",
  "build": "craco build",
  "test": "craco test",
  "eject": "react-scripts eject"
},
  1. Create a new file called craco.config.js in the root of the project with the following content:
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"),
        },
        extensions: [".mjs"],
      },
      plugins: [
        new webpack.ProvidePlugin({
          Buffer: ["buffer", "Buffer"],
          process: "process/browser",
        }),
      ],
      module: {
        rules: [
          {
            test: /\.m?js/,
            resolve: {
              fullySpecified: false,
            },
          },
        ],
      },
    },
  },
};

Hope this helps save your day!

D. Nguyen
  • 162
  • 10
0

Take a look at this example. In both host and remote directories there are very simple ways of overriding webpack config in cra without any ejecting or 3rd party libs.

Areestokrat
  • 31
  • 1
  • 5