Webpack 5错误 - 在ReactJS项目中无法解析'crypto','http'和'https'

25
我使用 npx create-react-app client 创建了一个新的React项目,并遇到了一些Webpack 5的问题。最初,我遇到了与assertosstream有关的错误,但通过安装它们并将其包含在webpack.config.js中已经解决了这些问题。该文件位于client/src文件夹中。
以下是这些错误的样子:
Compiled with problems:

    ERROR in ./node_modules/eth-lib/lib/bytes.js 9:193-227

    Module not found: Error: Can't resolve 'crypto' in 'C:\Users\Username\Projects\testProject\client\node_modules\eth-lib\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: { "crypto": require.resolve("crypto-browserify") }'
        - install 'crypto-browserify'
    If you don't want to include a polyfill, you can use an empty module like this:
        resolve.fallback: { "crypto": false }

=================================================================

    ERROR in ./node_modules/web3-providers-http/lib/index.js 30:11-26

    Module not found: Error: Can't resolve 'http' in 'C:\Users\Username\Projects\testProject\client\node_modules\web3-providers-http\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 }

=================================================================

    ERROR in ./node_modules/xhr2-cookies/dist/xml-http-request.js 39:12-28

    Module not found: Error: Can't resolve 'https' in 'C:\Users\Username\Projects\testProject\client\node_modules\xhr2-cookies\dist'

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

代码

这是我的webpack.config.js文件的当前样子。

module.exports = {
  resolve: {
    fallback: {
      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'),
      stream: require.resolve('stream-browserify'),
    },
  },
};

以下是我的package.json文件。
{
  "dependencies": {
    "assert": "^2.0.0",
    "crypto-browserify": "^3.12.0",
    "dotenv": "^10.0.0",
    "https-browserify": "^1.0.0",
    "os": "^0.1.2",
    "stream": "^0.0.2",
    "stream-http": "^3.2.0"
  }
}

从上面可以看到,我已经安装了错误提示中建议的包(crypto-browserifystream-httphttps-browserify),并将它们添加到了webpack.config.js文件中。然而,错误仍然存在。

我该如何解决这个问题?

4个回答

14

使用 react-app-rewired 工具可以解决这个问题,确保你已经安装了这个工具并在根目录下创建了一个名为 config-overrides.js 的新文件。

/* config-overrides.js */
const webpack = require('webpack');
module.exports = function override(config, env) {
    //do stuff with the webpack config...

    config.resolve.fallback = {
        url: require.resolve('url'),
        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;
}
现在编辑你的package.json以使react-app-rewired起作用。 //package.json
 "dependencies": {
    "@testing-library/jest-dom": "^5.16.1",
    "@testing-library/react": "^12.1.2",
    "@testing-library/user-event": "^13.5.0",
    "assert": "^2.0.0",
    "buffer": "^6.0.3",
    "crypto": "npm:crypto-browserify",
    "crypto-browserify": "^3.12.0",
    "https-browserify": "^1.0.0",
    "os-browserify": "^0.3.0",
    "react": "^17.0.2",
    "react-app-rewired": "^2.1.9",
    "react-dom": "^17.0.2",
    "react-scripts": "5.0.0",
    "rewire": "^6.0.0",
    "stream": "npm:stream-browserify",
    "stream-browserify": "^3.0.0",
    "stream-http": "^3.2.0",
    "url": "^0.11.0",
    "web-vitals": "^2.1.2",
    "web3": "^1.6.1"
  },
  "scripts": {
    "start": "react-app-rewired start",
    "build": "react-app-rewired build",
    "test": "react-app-rewired test",
    "eject": "react-app-rewired eject"
  },

我没有添加config-overrides.js文件。只更新了package.json,这对我有效。 - Mohit Prajapati

10

不使用Webpack 5的替代方案是降级到webpack@4.46.0react-scripts@4.0.3。在找到更好的解决方案之前,我会一直使用它。


5
整个重点是升级到 CRA 5 版本,以便获得安全更新(例如,v4 版本存在很多安全漏洞,可以参考 Dependabot 的建议)。因此,这不是一个选项... - trainoasis

5
这似乎是一个新问题,许多包都包括web3在内,没有为polyfils添加回退选项就无法与Webpack v5兼容。问题在此处记录:https://github.com/facebook/create-react-app/issues/11756。我通过在webpack.config.js文件中添加回退选项来解决了这个问题。
module.exports = {
    resolve: {
        fallback: {
            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'),
            stream: require.resolve('stream-browserify'),
        },
    },
};

使用;

"dependencies": {
    "@testing-library/jest-dom": "^5.16.1",
    "@testing-library/react": "^12.1.2",
    "@testing-library/user-event": "^13.5.0",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-scripts": "5.0.0",
    "web-vitals": "^2.1.2",
    "web3": "^1.6.1"
  },

但是在构建过程中出现编译错误,需要解决。
FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory" error

这个问题通过在我的.env文件中添加解决了;
GENERATE_SOURCEMAP=false

5
请勿将相同的答案粘贴到多个问题中。如果这些问题可以用相同的答案回答,那么请在其中一个问题上发布一个好的答案,并将其他问题标记为重复。如果它们不是重复的,请根据特定问题量身定制答案,而不仅仅是剪切/粘贴。 - David Buck

2
除此之外,还可以使用react-app-rewired包的技巧。
因此,1)安装react-app-rewired 2)在packages.json中将react-scripts替换为react-app-rewired,例如:
 "start": "rimraf ./build && react-scripts start",

变为

"start": "rimraf ./build && react-app-rewired start",
  1. 将以下内容复制并粘贴到config-overrides.js文件中(位于您的应用程序根目录下)
    // config-overrides.js
    module.exports = function override(config, env) {
       // New config, e.g. config.plugins.push...
       // console.log(JSON.stringify(config.resolve.fallback))
        config.resolve.fallback = {
            crypto: false,
            util: false,
            stream: false,
            ...config.resolve.fallback
        };  
        return config
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接