reactjs 无法将web3添加到React项目

vaqhlq81  于 2023-01-17  发布在  React
关注(0)|答案(5)|浏览(129)

I'm trying to add Web3 to a React project. I've initalized a new project with

gatsby new

Then, I've installed web3

npm install --save web3

And when I include web3 in index.js

import Web3 from 'web3'

And if I call

gatsby develop

I have some strange errors :
ERROR in ./node_modules/eth-lib/lib/bytes.js 9:193-227 Module not found: Error: Can't resolve 'crypto' in '/home/test/gatsby/test/test/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 24:12-31  @ ./node_modules/web3/lib/index.js 34:10-29  @ ./src/pages/index.js 9:0-24  @ ./.cache/this_is_virtual_fs_path/$virtual/async-requires.js 21:11-23:5  @ ./.cache/app.js 17:0-52 28:0-70 30:27-40 28:0-70
ERROR in ./node_modules/ethereumjs-util/dist/account.js 4:13-30 Module not found: Error: Can't resolve 'assert' in >'/home/test/gatsby/test/test/node_modules/ethereumjs-util/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: { "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/index.js 29:13-33  @ ./node_modules/ethereumjs-tx/dist/transaction.js 14:24-50  @ ./node_modules/ethereumjs-tx/dist/index.js 3:20-44  @ ./node_modules/web3-eth-accounts/lib/index.js 35:18-54  @ ./node_modules/web3-eth/lib/index.js 34:15-43  @ ./node_modules/web3/lib/index.js 30:10-29  @ ./src/pages/index.js 9:0-24  @ ./.cache/this_is_virtual_fs_path/$virtual/async-requires.js 21:11-23:5  @ ./.cache/app.js 17:0-52 28:0-70 30:27-40 28:0-70
ERROR in ./node_modules/ethereumjs-util/dist/object.js 4:13-30 Module not found: Error: Can't resolve 'assert' in >'/home/test/gatsby/test/test/node_modules/ethereumjs-util/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: { "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/index.js 45:13-32  @ ./node_modules/ethereumjs-tx/dist/transaction.js 14:24-50  @ ./node_modules/ethereumjs-tx/dist/index.js 3:20-44  @ ./node_modules/web3-eth-accounts/lib/index.js 35:18-54  @ ./node_modules/web3-eth/lib/index.js 34:15-43  @ ./node_modules/web3/lib/index.js 30:10-29  @ ./src/pages/index.js 9:0-24  @ ./.cache/this_is_virtual_fs_path/$virtual/async-requires.js 21:11-23:5  @ ./.cache/app.js 17:0-52 28:0-70 30:27-40 28:0-70
ERROR in ./node_modules/web3-eth-accounts/lib/index.js 30:76-93 Module not found: Error: Can't resolve 'crypto' in '/home/test/gatsby/test/test/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 34:15-43  @ ./node_modules/web3/lib/index.js 30:10-29  @ ./src/pages/index.js 9:0-24  @ ./.cache/this_is_virtual_fs_path/$virtual/async-requires.js 21:11-23:5  @ ./.cache/app.js 17:0-52 28:0-70 30:27-40 28:0-70
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 '/home/test/gatsby/test/test/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/lib/index.js 29:12-40  @ ./node_modules/web3-eth/lib/index.js 34:15-43  @ ./node_modules/web3/lib/index.js 30:10-29  @ ./src/pages/index.js 9:0-24  @ ./.cache/this_is_virtual_fs_path/$virtual/async-requires.js 21:11-23:5  @ ./.cache/app.js 17:0-52 28:0-70 30:27-40 28:0-70
ERROR in ./node_modules/web3-providers-http/lib/index.js 26:11-26 Module not found: Error: Can't resolve 'http' in '/home/test/gatsby/test/test/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 46:18-48  @ ./node_modules/web3-core/lib/index.js 22:23-58  @ ./node_modules/web3/lib/index.js 29:11-31  @ ./src/pages/index.js 9:0-24  @ ./.cache/this_is_virtual_fs_path/$virtual/async-requires.js 21:11-23:5  @ ./.cache/app.js 17:0-52 28:0-70 30:27-40 28:0-70
ERROR in ./node_modules/web3-providers-http/lib/index.js 27:12-28 Module not found: Error: Can't resolve 'https' in '/home/test/gatsby/test/test/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 46:18-48  @ ./node_modules/web3-core/lib/index.js 22:23-58  @ ./node_modules/web3/lib/index.js 29:11-31  @ ./src/pages/index.js 9:0-24  @ ./.cache/this_is_virtual_fs_path/$virtual/async-requires.js 21:11-23:5  @ ./.cache/app.js 17:0-52 28:0-70 30:27-40 28:0-70
ERROR in ./node_modules/xhr2-cookies/dist/xml-http-request.js 21:11-26 Module not found: Error: Can't resolve 'http' in '/home/test/gatsby/test/test/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 46:18-48  @ ./node_modules/web3-core/lib/index.js 22:23-58  @ ./node_modules/web3/lib/index.js 29:11-31  @ ./src/pages/index.js 9:0-24  @ ./.cache/this_is_virtual_fs_path/$virtual/async-requires.js 21:11-23:5  @ ./.cache/app.js 17:0-52 28:0-70 30:27-40 28:0-70
ERROR in ./node_modules/xhr2-cookies/dist/xml-http-request.js 22:12-28 Module not found: Error: Can't resolve 'https' in '/home/test/gatsby/test/test/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 46:18-48  @ ./node_modules/web3-core/lib/index.js 22:23-58  @ ./node_modules/web3/lib/index.js 29:11-31  @ ./src/pages/index.js 9:0-24  @ ./.cache/this_is_virtual_fs_path/$virtual/async-requires.js 21:11-23:5  @ ./.cache/app.js 17:0-52 28:0-70 30:27-40 28:0-70
ERROR in ./node_modules/xhr2-cookies/dist/xml-http-request.js 23:9-22 Module not found: Error: Can't resolve 'os' in '/home/test/gatsby/test/test/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 46:18-48  @ ./node_modules/web3-core/lib/index.js 22:23-58  @ ./node_modules/web3/lib/index.js 29:11-31  @ ./src/pages/index.js 9:0-24  @ ./.cache/this_is_virtual_fs_path/$virtual/async-requires.js 21:11-23:5  @ ./.cache/app.js 17:0-52 28:0-70 30:27-40 28:0-70
webpack compiled with 10 errors
I've tried to install these modules manually, add them in package.json, etc. But nothing works.
Can you help me?

p5fdfcr1

p5fdfcr11#

这对我很有效。将以下内容添加到您的gatsby-node.js配置:

const webpack = require("webpack");

exports.onCreateWebpackConfig = ({ actions }) => {
    actions.setWebpackConfig({
        plugins: [
            new webpack.ProvidePlugin({
                Buffer: [require.resolve("buffer/"), "Buffer"],
            }),
        ],
        resolve: {
            fallback: {
                "crypto": false,
                "stream": require.resolve("stream-browserify"),
                "assert": false,
                "util": false,
                "http": false,
                "https": false,
                "os": false
            },
        },
    })
}
kxe2p93d

kxe2p93d2#

不幸的是,大多数Web 3堆栈严重依赖于窗口、浏览器和外部的加密依赖,而这些在服务器端是不可用的。这不仅仅是Gatsby的问题,其他SSR和静态站点生成器(例如Next.js)也是如此。
不过有一些变通方法。请参见Using Client-Side Only Packages on Gatsby
1.使用不同的库或方法
1.通过CDN添加客户端包
1.使用可加载组件加载客户端依赖组件
1.仅在客户端使用React.lazy和Suspense
根据您的需求,#1可能不是一个选项。我使用ethers而不是web 3取得了更好的成功。但在某些时候,您可能会在其他软件包中遇到类似的问题。
第二步和第三步的组合是可行的。首先,删除导致问题的软件包(web 3),然后从gatsby-browser.js或使用react-helmet的页面/组件加载它们。

gatsby浏览器.js

const addScript = url => {
  const script = document.createElement("script")
  script.src = url
  script.async = true
  document.body.appendChild(script)
}

export const onClientEntry = () => {
  window.onload = () => {
    addScript("https://cdn.jsdelivr.net/npm/web3@latest/dist/web3.min.js")
  }
}

**反作用 Helm **

<Helmet>
    <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/web3@latest/dist/web3.min.js" />
</Helmet>

现在你应该可以使用web 3了。确保检查你是否在浏览器中运行,使用typeof window !== "undefined"。一个完整的代码示例:

import React from 'react'
import { Helmet } from "react-helmet"

export default function Web3() {
    const [blockNr, setBlockNr] = React.useState()
    const isBrowser = typeof window !== "undefined"

    async function getBlockNumber() {
        console.log('Init web3')
        const web3 = new window.Web3('https://cloudflare-eth.com')
        const currentBlockNumber = await web3.eth.getBlockNumber()
        setBlockNr(currentBlockNumber)        
    }

    return (
        <div>
            {/* Can use either react-helmet or include the script from gatsby-browser */}
            <Helmet>
                <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/web3@latest/dist/web3.min.js" />
            </Helmet>
            {isBrowser && 
                <div>
                    <p>Running in browser..</p>
                    <button onClick={getBlockNumber}>Get Block #</button>
                </div>
            }
            
            {blockNr && <span>{blockNr}</span>}
        </div>
    )
}

你可能仍然希望加载的东西懒惰或使用可加载的组件。

const LazyWeb3BlockNr = React.lazy(() =>
  import("../components/Web3BlockNr")
)

在你的页面里

<div>
    {typeof window !== "undefined" && 
        <React.Suspense fallback={<div />}>
            <LazyWeb3BlockNr />
        </React.Suspense>
    }
</div>

https://github.com/wslyvh/web3-gatsby的完整代码示例

e5nqia27

e5nqia273#

执行以下操作:

npm install --save-dev react-app-rewired crypto-browserify stream-browserify assert stream-http https-browserify os-browserify url buffer process

在根目录中创建一个config-overrides.js并添加:

const webpack = require('webpack');

module.exports = function override(config) {
    const fallback = config.resolve.fallback || {};
    Object.assign(fallback, {
        "crypto": require.resolve("crypto-browserify"),
        "stream": require.resolve("stream-browserify"),
        "assert": require.resolve("assert"),
        "http": require.resolve("stream-http"),
        "https": require.resolve("https-browserify"),
        "os": require.resolve("os-browserify"),
        "url": require.resolve("url")
    })
    config.resolve.fallback = fallback;
    config.plugins = (config.plugins || []).concat([
        new webpack.ProvidePlugin({
            process: 'process/browser',
            Buffer: ['buffer', 'Buffer']
        })
    ])
    return config;
}

现在将package.json中的scripts:更改为:

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

瞧,在浪费了许多小时后为我工作了!

mwyxok5s

mwyxok5s4#

webpack 5 issue documentation
https://web3auth.io/docs/troubleshooting/webpack-issues

steps:-
1 run this command inside react folder 
>>npm install --save-dev react-app-rewired crypto-browserify stream-browserify assert stream-http https-browserify os-browserify url buffer process

2.Create config-overrides.js in the root of your project folder with the content:
 
content of this page
const webpack = require("webpack");

module.exports = function override(config) {
  const fallback = config.resolve.fallback || {};
  Object.assign(fallback, {
    crypto: require.resolve("crypto-browserify"),
    stream: require.resolve("stream-browserify"),
    assert: require.resolve("assert"),
    http: require.resolve("stream-http"),
    https: require.resolve("https-browserify"),
    os: require.resolve("os-browserify"),
    url: require.resolve("url"),
  });
  config.resolve.fallback = fallback;
  config.plugins = (config.plugins || []).concat([
    new webpack.ProvidePlugin({
      process: "process/browser",
      Buffer: ["buffer", "Buffer"],
    }),
  ]);
  return config;
};

3>Within package.json of react.js change the scripts field for start, build and test. Instead of react-scripts replace it with react-app-rewired

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

4>>
The missing Nodejs polyfill should be included now and your app should be functional with web3.

If you want to hide the warnings created by the console:
In config-overrides.js within the override function, add

     config. ignoreWarnings

  = [/Failed to parse source map/];
lkaoscv7

lkaoscv75#

如果你不想手动安装每个插件包,你可以使用node-polyfill-webpack-plugin插件包。链接的README有更多关于如何定制插件的例子,但是你可以简单地添加它:

const NodePolyfillPlugin = require('node-polyfill-webpack-plugin');

module.exports = {
    // Other rules...
    plugins: [
        new NodePolyfillPlugin()
    ]
};

到你的webpack.config.js

相关问题