如何在反应中使用 webpack 和 web3?

Posted

技术标签:

【中文标题】如何在反应中使用 webpack 和 web3?【英文标题】:how to use webpack and web3 in react? 【发布时间】:2021-11-24 14:45:34 【问题描述】:

您好,我刚刚从 skratch 启动了一个新的 react 应用程序。我按照https://medium.com/age-of-awareness/setup-react-with-webpack-and-babel-5114a14a47e9 的说明进行操作 这是我的 package.json 文件


  "name": "html2",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": 
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "webpack serve --mode development",
    "build": "webpack --mode production"
  ,
  "author": "",
  "license": "ISC",
  "dependencies": 
    "react": "^17.0.2",
    "react-dom": "^17.0.2"
  ,
  "devDependencies": 
    "@babel/core": "^7.15.5",
    "@babel/plugin-syntax-dynamic-import": "^7.8.3",
    "@babel/preset-env": "^7.15.6",
    "@babel/preset-react": "^7.14.5",
    "babel-loader": "^8.2.2",
    "compression-webpack-plugin": "^9.0.0",
    "html-webpack-plugin": "^5.3.2",
    "webpack": "^5.56.0",
    "webpack-cli": "^4.8.0",
    "webpack-dev-server": "^4.3.0"
  

一切顺利,运行和构建,直到我尝试添加 web3 包。我用

npm install web3 --save-dev

安装包并使用

将它引用到我的 index.js 文件中
import Web3 from "web3";

之后,如果我尝试运行或构建,我得到了很多错误:

ERROR in ./node_modules/cipher-base/index.js 2:16-43
Module not found: Error: Can't resolve 'stream' in 'C:\developer\RFT\html2\node_modules\cipher-base'

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 
 @ ./node_modules/create-hash/browser.js 6:11-33
 @ ./node_modules/ethereumjs-util/dist.browser/hash.js 24:17-39
 @ ./node_modules/ethereumjs-util/dist.browser/index.js 30:13-30
 @ ./node_modules/web3-utils/lib/utils.js 25:21-47
 @ ./node_modules/web3-utils/lib/index.js 24:12-33
 @ ./node_modules/web3/lib/index.js 35:12-33
 @ ./src/index.js 3:0-24

ERROR in ./node_modules/eth-lib/lib/bytes.js 9:193-227
Module not found: Error: Can't resolve 'crypto' in 'C:\developer\RFT\html2\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 
 @ ./node_modules/swarm-js/lib/api-browser.js 32:12-40
 @ ./node_modules/web3-bzz/lib/index.js 23:12-31
 @ ./node_modules/web3/lib/index.js 34:10-29
 @ ./src/index.js 3:0-24

ERROR in ./node_modules/ethereumjs-util/dist.browser/account.js 42:31-48
Module not found: Error: Can't resolve 'assert' in 'C:\developer\RFT\html2\node_modules\ethereumjs-util\dist.browser'

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:  "assert": require.resolve("assert/") '
        - install 'assert'
If you don't want to include a polyfill, you can use an empty module like this:
        resolve.fallback:  "assert": false 
 @ ./node_modules/ethereumjs-util/dist.browser/index.js 22:13-33
 @ ./node_modules/web3-utils/lib/utils.js 25:21-47
 @ ./node_modules/web3-utils/lib/index.js 24:12-33
 @ ./node_modules/web3/lib/index.js 35:12-33
 @ ./src/index.js 3:0-24

ERROR in ./node_modules/ethereumjs-util/dist.browser/address.js 7:31-48
Module not found: Error: Can't resolve 'assert' in 'C:\developer\RFT\html2\node_modules\ethereumjs-util\dist.browser'

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:  "assert": require.resolve("assert/") '
        - install 'assert'
If you don't want to include a polyfill, you can use an empty module like this:
        resolve.fallback:  "assert": false 
 @ ./node_modules/ethereumjs-util/dist.browser/index.js 26:13-33
 @ ./node_modules/web3-utils/lib/utils.js 25:21-47
 @ ./node_modules/web3-utils/lib/index.js 24:12-33
 @ ./node_modules/web3/lib/index.js 35:12-33
 @ ./src/index.js 3:0-24

ERROR in ./node_modules/ethereumjs-util/dist.browser/object.js 26:31-48
Module not found: Error: Can't resolve 'assert' in 'C:\developer\RFT\html2\node_modules\ethereumjs-util\dist.browser'

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:  "assert": require.resolve("assert/") '
        - install 'assert'
If you don't want to include a polyfill, you can use an empty module like this:
        resolve.fallback:  "assert": false 
 @ ./node_modules/ethereumjs-util/dist.browser/index.js 42:13-32
 @ ./node_modules/web3-utils/lib/utils.js 25:21-47
 @ ./node_modules/web3-utils/lib/index.js 24:12-33
 @ ./node_modules/web3/lib/index.js 35:12-33
 @ ./src/index.js 3:0-24

ERROR in ./node_modules/web3-eth-accounts/lib/index.js 26:76-93
Module not found: Error: Can't resolve 'crypto' in 'C:\developer\RFT\html2\node_modules\web3-eth-accounts\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 
 @ ./node_modules/web3-eth/lib/index.js 33:15-43
 @ ./node_modules/web3/lib/index.js 30:10-29
 @ ./src/index.js 3:0-24

ERROR in ./node_modules/web3-eth-accounts/node_modules/eth-lib/lib/bytes.js 7:193-227
Module not found: Error: Can't resolve 'crypto' in 'C:\developer\RFT\html2\node_modules\web3-eth-accounts\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 
 @ ./node_modules/web3-eth-accounts/node_modules/eth-lib/lib/account.js 1:14-32
 @ ./node_modules/web3-eth-accounts/lib/index.js 25:14-44
 @ ./node_modules/web3-eth/lib/index.js 33:15-43
 @ ./node_modules/web3/lib/index.js 30:10-29
 @ ./src/index.js 3:0-24

ERROR in ./node_modules/web3-providers-http/lib/index.js 26:11-26
Module not found: Error: Can't resolve 'http' in 'C:\developer\RFT\html2\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 
 @ ./node_modules/web3-core-requestmanager/lib/index.js 45:18-48
 @ ./node_modules/web3-core/lib/index.js 22:23-58
 @ ./node_modules/web3/lib/index.js 29:11-31
 @ ./src/index.js 3:0-24

ERROR in ./node_modules/web3-providers-http/lib/index.js 27:12-28
Module not found: Error: Can't resolve 'https' in 'C:\developer\RFT\html2\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:  "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 
 @ ./node_modules/web3-core-requestmanager/lib/index.js 45:18-48
 @ ./node_modules/web3-core/lib/index.js 22:23-58
 @ ./node_modules/web3/lib/index.js 29:11-31
 @ ./src/index.js 3:0-24

ERROR in ./node_modules/xhr2-cookies/dist/xml-http-request.js 21:11-26
Module not found: Error: Can't resolve 'http' in 'C:\developer\RFT\html2\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:  "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 
 @ ./node_modules/xhr2-cookies/dist/index.js 6:9-38
 @ ./node_modules/web3-providers-http/lib/index.js 25:11-49
 @ ./node_modules/web3-core-requestmanager/lib/index.js 45:18-48
 @ ./node_modules/web3-core/lib/index.js 22:23-58
 @ ./node_modules/web3/lib/index.js 29:11-31
 @ ./src/index.js 3:0-24

ERROR in ./node_modules/xhr2-cookies/dist/xml-http-request.js 22:12-28
Module not found: Error: Can't resolve 'https' in 'C:\developer\RFT\html2\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 
 @ ./node_modules/xhr2-cookies/dist/index.js 6:9-38
 @ ./node_modules/web3-providers-http/lib/index.js 25:11-49
 @ ./node_modules/web3-core-requestmanager/lib/index.js 45:18-48
 @ ./node_modules/web3-core/lib/index.js 22:23-58
 @ ./node_modules/web3/lib/index.js 29:11-31
 @ ./src/index.js 3:0-24

ERROR in ./node_modules/xhr2-cookies/dist/xml-http-request.js 23:9-22
Module not found: Error: Can't resolve 'os' in 'C:\developer\RFT\html2\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:  "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 
 @ ./node_modules/xhr2-cookies/dist/index.js 6:9-38
 @ ./node_modules/web3-providers-http/lib/index.js 25:11-49
 @ ./node_modules/web3-core-requestmanager/lib/index.js 45:18-48
 @ ./node_modules/web3-core/lib/index.js 22:23-58
 @ ./node_modules/web3/lib/index.js 29:11-31
 @ ./src/index.js 3:0-24

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

webpack 5.56.0 compiled with 12 errors in 14277 ms

发生了什么事?我正在尝试这个解决方案,因为我的原始项目是在没有 webpack 的情况下做出反应(我认为 browserfy)并且一切正常,但我认为块(即使拆分)非常大(在某些情况下超过 3MB)。我无法优化它,我想到了 webpack。对吗?

谢谢

【问题讨论】:

【参考方案1】:

问题是webpack 不再为您解决列在here 中的节点核心模块。基本上有 2 个选项可以解决与您使用的特定软件包相关的问题 web3

选项#1:这只是使用已经为位于dist/web3.min.jsweb 构建的直接版本。因此,然后将您的导入切换为:
import Web3 from "web3/dist/web3.min";

但是,如果您的代码是 Typescript,这种方式最终可能会导致输入问题。

选项#2:这种方式与他们构建web3.min.js 作为步骤1 的方式相同,但它发生在您的webpack5 上。为了解决节点核心模块,您可以添加上面的fallback 列表并安装它们所需的包或使用this one 让生活更轻松。请记住,不要将 node_modules 从 JS 代码的加载器中排除(babel-loader 始终是常见的加载器)。这是草稿:
// webpack.config.js

  // ...
  plugins: [
    new NodePolyfillPlugin(
      excludeAliases: ["console"]
    ),
  ]
  // ...

【讨论】:

谢谢!现在我想知道我的猜测是否正确:我应该使用 webpack 来减少块还是即使使用我的 origina 项目也有办法做到这一点? 不确定你的意思是什么? 我的网站速度很慢(没有来自 chrome 的缓存)。对于 3MB 的内容,下载最大块(其中一个块)的总时间约为 40 秒(我认为现在这是我的连接和网络服务器的问题)。无论如何我需要减少这个,我认为 webpack 有更多的选择。不是吗? 是的,它有几种技术。基本上你可能知道分割更小的块可以更快地加载。此外,您可以使用 webpack 搜索代码拆分,这是关于删除未使用的代码,从而使包更小。

以上是关于如何在反应中使用 webpack 和 web3?的主要内容,如果未能解决你的问题,请参考以下文章

如何让服务器将远程 json 对象返回给客户端?反应/快递/web3

反应,流星,webpack,es6。如何创建加载/启动屏幕

如何实现 SASS 以与原始 webpack 做出反应?

反应错误:未定义 web3' no-undef

如何使用 Webpack 创建与容器应用程序共享库的微前端包?

如何在捆绑时减少反应应用程序构建时间和理解 webpack 的行为