无法将 web3 添加到 React 项目

Kar*_*nen 8 reactjs web3js

我正在尝试将 Web3 添加到 React 项目。\n我已经使用以下命令初始化了一个新项目

\n
gatsby new\n
Run Code Online (Sandbox Code Playgroud)\n

然后,我安装了web3

\n
npm install --save web3\n
Run Code Online (Sandbox Code Playgroud)\n

当我在 index.js 中包含 web3 时

\n
import Web3 from 'web3'\n
Run Code Online (Sandbox Code Playgroud)\n

如果我打电话

\n
gatsby develop\n
Run Code Online (Sandbox Code Playgroud)\n

我有一些奇怪的错误:

\n
\n

./node_modules/eth-lib/lib/bytes.js 9:193-227\n中出现错误:找不到模块:错误:无法解析“/home/test/gatsby/test/test/node_modules/eth”中的“加密” -lib/lib'

\n
\n
\n

重大更改:webpack < 5 过去默认包含 Node.js 核心模块的 Polyfill。\n现在情况已不再如此。验证您是否需要此模块并为其配置一个polyfill。

\n
\n
\n

如果你想包含一个polyfill,你需要:\n- 添加后备 'resolve.fallback: { "crypto": require.resolve("crypto-browserify") }'\n- 安装 'crypto-browserify'\如果你不想包含一个polyfill,你可以使用一个空模块,如下所示:\nresolve.fallback: { "crypto": false }\n\xc2\xa0@ ./node_modules/swarm-js/lib/api -browser.js 32:12-40\n\xc2\xa0@ ./node_modules/web3-bzz/lib/index.js 24:12-31\n\xc2\xa0@ ./node_modules/web3/lib/index .js 34:10-29\n\xc2\xa0@ ./src/pages/index.js 9:0-24\n\xc2\xa0@ ./.cache/ this_is_virtual_fs_path /$virtual/async-requires.js 21:11-23:5\n\xc2\xa0@ ./.cache/app.js 17:0-52 28:0-70 30:27-40 28:0-70

\n

./node_modules/ethereumjs-util/dist/account.js 4:13-30\n中出现错误:找不到模块:错误:无法解析 >'/home/test/gatsby/test/test/node_modules/ 中的“assert” ethereumjs-util/dist'

\n

重大更改:webpack < 5 过去默认包含 Node.js 核心模块的 Polyfill。\n现在情况已不再如此。验证您是否需要此模块并为其配置一个polyfill。

\n
\n
\n

如果你想包含一个polyfill,你需要:\n- 添加一个后备 'resolve.fallback: { "assert": require.resolve("assert/") }'\n- 安装 'assert'\n如果你不这样做不想包含填充,您可以使用这样的空模块:\nresolve.fallback: { "assert": false }\n\xc2\xa0@ ./node_modules/ethereumjs-util/dist/index.js 29 :13-33\n\xc2\xa0@ ./node_modules/ethereumjs-tx/dist/transaction.js 14:24-50\n\xc2\xa0@ ./node_modules/ethereumjs-tx/dist/index.js 3 :20-44\n\xc2\xa0@ ./node_modules/web3-eth-accounts/lib/index.js 35:18-54\n\xc2\xa0@ ./node_modules/web3-eth/lib/index.js Node.js 34:15-43\n\xc2\xa0@ ./node_modules/web3/lib/index.js 30:10-29\n\xc2\xa0@ ./src/pages/index.js 9:0-24 \n\xc2\xa0@ ./.cache/ this_is_virtual_fs_path /$virtual/async-requires.js 21:11-23:5\n\xc2\xa0@ ./.cache/app.js 17:0-52 28 :0-70 30:27-40 28:0-70

\n
\n
\n

./node_modules/ethereumjs-util/dist/object.js 4:13-30\n中出现错误:找不到模块:错误:无法解析 >'/home/test/gatsby/test/test/node_modules/ 中的“assert” ethereumjs-util/dist'

\n
\n
\n

重大更改:webpack < 5 过去默认包含 Node.js 核心模块的 Polyfill。\n现在情况已不再如此。验证您是否需要此模块并为其配置一个polyfill。

\n
\n
\n

如果你想包含一个polyfill,你需要:\n- 添加一个后备 'resolve.fallback: { "assert": require.resolve("assert/") }'\n- 安装 'assert'\n如果你不这样做不想包含填充,您可以使用这样的空模块:\nresolve.fallback: { "assert": false }\n\xc2\xa0@ ./node_modules/ethereumjs-util/dist/index.js 45 :13-32\n\xc2\xa0@ ./node_modules/ethereumjs-tx/dist/transaction.js 14:24-50\n\xc2\xa0@ ./node_modules/ethereumjs-tx/dist/index.js 3 :20-44\n\xc2\xa0@ ./node_modules/web3-eth-accounts/lib/index.js 35:18-54\n\xc2\xa0@ ./node_modules/web3-eth/lib/index.js Node.js 34:15-43\n\xc2\xa0@ ./node_modules/web3/lib/index.js 30:10-29\n\xc2\xa0@ ./src/pages/index.js 9:0-24 \n\xc2\xa0@ ./.cache/ this_is_virtual_fs_path /$virtual/async-requires.js 21:11-23:5\n\xc2\xa0@ ./.cache/app.js 17:0-52 28 :0-70 30:27-40 28:0-70

\n
\n
\n

./node_modules/web3-eth-accounts/lib/index.js 30:76-93\n中的错误:找不到模块:错误:无法解析“/home/test/gatsby/test/test/node_modules”中的“加密” /web3->eth-accounts/lib'

\n
\n
\n

重大更改:webpack < 5 过去默认包含 Node.js 核心模块的 Polyfill。\n现在情况已不再如此。验证您是否需要此模块并为其配置一个polyfill。

\n
\n
\n

如果你想包含一个polyfill,你需要:\n- 添加后备 'resolve.fallback: { "crypto": require.resolve("crypto-browserify") }'\n- 安装 'crypto-browserify'\如果你不想包含一个polyfill,你可以使用一个空模块,如下所示:\nresolve.fallback: { "crypto": false }\n\xc2\xa0@ ./node_modules/web3-eth/lib/index .js 34:15-43\n\xc2\xa0@ ./node_modules/web3/lib/index.js 30:10-29\n\xc2\xa0@ ./src/pages/index.js 9:0- 24\n\xc2\xa0@ ./.cache/ this_is_virtual_fs_path /$virtual/async-requires.js 21:11-23:5\n\xc2\xa0@ ./.cache/app.js 17:0-52 28:0-70 30:27-40 28:0-70

\n
\n
\n

./node_modules/web3-eth-accounts/node_modules/eth-lib/lib/bytes.js 中出现错误 7:193-227\n找不到模块:错误:无法解析“/home/test/gatsby”中的“加密” /测试/测试/node_modules/web3-eth-accounts/node_modules/eth-lib/lib'

\n
\n
\n

重大更改:webpack < 5 过去默认包含 Node.js 核心模块的 Polyfill。\n现在情况已不再如此。验证您是否需要此模块并为其配置一个polyfill。

\n
\n
\n

如果你想包含一个polyfill,你需要:\n- 添加后备 'resolve.fallback: { "crypto": require.resolve("crypto-browserify") }'\n- 安装 'crypto-browserify'\如果你不想包含一个polyfill,你可以使用一个空模块,如下所示:\nresolve.fallback: { "crypto": false }\n\xc2\xa0@ ./node_modules/web3-eth-accounts/lib /index.js 29:12-40\n\xc2\xa0@ ./node_modules/web3-eth/lib/index.js 34:15-43\n\xc2\xa0@ ./node_modules/web3/lib/index .js 30:10-29\n\xc2\xa0@ ./src/pages/index.js 9:0-24\n\xc2\xa0@ ./.cache/ this_is_virtual_fs_path /$virtual/async-requires.js 21:11-23:5\n\xc2\xa0@ ./.cache/app.js 17:0-52 28:0-70 30:27-40 28:0-70

\n
\n
\n

./node_modules/web3-providers-http/lib/index.js 26:11-26\n中出现错误:找不到模块:错误:无法解析“/home/test/gatsby/test/test/node_modules”中的“http” /web3-providers-http/lib'

\n
\n
\n

重大更改:webpack < 5 过去默认包含 Node.js 核心模块的 Polyfill。\n现在情况已不再如此。验证您是否需要此模块并为其配置一个polyfill。

\n
\n
\n

如果你想包含一个polyfill,你需要:\n- 添加后备 'resolve.fallback: { "http": require.resolve("stream-http") }'\n- 安装 'stream-http'\如果你不想包含一个polyfill,你可以使用一个空模块,如下所示:\nresolve.fallback: { "http": false }\n\xc2\xa0@ ./node_modules/web3-core-requestmanager/lib /index.js 46:18-48\n\xc2\xa0@ ./node_modules/web3-core/lib/index.js 22:23-58\n\xc2\xa0@ ./node_modules/web3/lib/index .js 29:11-31\n\xc2\xa0@ ./src/pages/index.js 9:0-24\n\xc2\xa0@ ./.cache/ this_is_virtual_fs_path /$virtual/async-requires.js 21:11-23:5\n\xc2\xa0@ ./.cache/app.js 17:0-52 28:0-70 30:27-40 28:0-70

\n
\n
\n

./node_modules/web3-providers-http/lib/index.js 27:12-28\n中出现错误:找不到模块:错误:无法解析“/home/test/gatsby/test/test/node_modules”中的“https” /web3-providers-http/lib'

\n
\n
\n

重大更改:webpack < 5 过去默认包含 Node.js 核心模块的 Polyfill。\n现在情况已不再如此。验证您是否需要此模块并为其配置一个polyfill。

\n
\n
\n

如果你想包含一个polyfill,你需要:\n- 添加后备 'resolve.fallback: { "https": require.resolve("https-browserify") }'\n- 安装 'https-browserify'\如果你不想包含一个polyfill,你可以使用一个空模块,如下所示:\nresolve.fallback: { "https": false }\n\xc2\xa0@ ./node_modules/web3-core-requestmanager/lib /index.js 46:18-48\n\xc2\xa0@ ./node_modules/web3-core/lib/index.js 22:23-58\n\xc2\xa0@ ./node_modules/web3/lib/index .js 29:11-31\n\xc2\xa0@ ./src/pages/index.js 9:0-24\n\xc2\xa0@ ./.cache/ this_is_virtual_fs_path /$virtual/async-requires.js 21:11-23:5\n\xc2\xa0@ ./.cache/app.js 17:0-52 28:0-70 30:27-40 28:0-70

\n
\n
\n

./node_modules/xhr2-cookies/dist/xml-http-request.js 21:11-26\n中出现错误:找不到模块:错误:无法解析“/home/test/gatsby/test/test”中的“http” /node_modules/xhr2-cookies/dist'

\n
\n
\n

重大更改:webpack < 5 过去默认包含 Node.js 核心模块的 Polyfill。\n现在情况已不再如此。验证您是否需要此模块并为其配置一个polyfill。

\n
\n
\n

如果你想包含一个polyfill,你需要:\n- 添加后备 'resolve.fallback: { "http": require.resolve("stream-http") }'\n- 安装 'stream-http'\如果你不想包含一个polyfill,你可以使用一个空模块,如下所示:\nresolve.fallback: { "http": false }\n\xc2\xa0@ ./node_modules/xhr2-cookies/dist/index .js 6:9-38\n\xc2\xa0@ ./node_modules/web3-providers-http/lib/index.js 25:11-49\n\xc2\xa0@ ./node_modules/web3-core-requestmanager /lib/index.js 46:18-48\n\xc2\xa0@ ./node_modules/web3-core/lib/index.js 22:23-58\n\xc2\xa0@ ./node_modules/web3/lib /index.js 29:11-31\n\xc2\xa0@ ./src/pages/index.js 9:0-24\n\xc2\xa0@ ./.cache/ this_is_virtual_fs_path /$virtual/async-requires .js 21:11-23:5\n\xc2\xa0@ ./.cache/app.js 17:0-52 28:0-70 30:27-40 28:0-70

\n
\n
\n

./node_modules/xhr2-cookies/dist/xml-http-request.js 22:12-28\n中出现错误:找不到模块:错误:无法解析“/home/test/gatsby/test/test”中的“https” /node_modules/xhr2-cookies/dist'

\n
\n
\n

重大更改:webpack < 5 过去默认包含 Node.js 核心模块的 Polyfill。\n现在情况已不再如此。验证您是否需要此模块并为其配置一个polyfill。

\n
\n
\n

如果你想包含一个polyfill,你需要:\n- 添加后备 'resolve.fallback: { "https": require.resolve("https-browserify") }'\n- 安装 'https-browserify'\如果你不想包含一个polyfill,你可以使用一个空模块,如下所示:\nresolve.fallback: { "https": false }\n\xc2\xa0@ ./node_modules/xhr2-cookies/dist/index .js 6:9-38\n\xc2\xa0@ ./node_modules/web3-providers-http/lib/index.js 25:11-49\n\xc2\xa0@ ./node_modules/web3-core-requestmanager /lib/index.js 46:18-48\n\xc2\xa0@ ./node_modules/web3-core/lib/index.js 22:23-58\n\xc2\xa0@ ./node_modules/web3/lib /index.js 29:11-31\n\xc2\xa0@ ./src/pages/index.js 9:0-24\n\xc2\xa0@ ./.cache/ this_is_virtual_fs_path /$virtual/async-requires .js 21:11-23:5\n\xc2\xa0@ ./.cache/app.js 17:0-52 28:0-70 30:27-40 28:0-70

\n
\n
\n

./node_modules/xhr2-cookies/dist/xml-http-request.js 23:9-22\n中出现错误:找不到模块:错误:无法解析“/home/test/gatsby/test/test”中的“os” /node_modules/xhr2-cookies/dist'

\n
\n
\n

重大更改:webpack < 5 过去默认包含 Node.js 核心模块的 Polyfill。\n现在情况已不再如此。验证您是否需要此模块并为其配置一个polyfill。

\n
\n
\n

如果你想包含一个polyfill,你需要:\n- 添加后备 'resolve.fallback: { "os": require.resolve("os-browserify/browser") }'\n- 安装 'os-browserify '\n如果你不想包含一个polyfill,你可以使用一个空模块,如下所示:\nresolve.fallback: { "os": false }\n\xc2\xa0@ ./node_modules/xhr2-cookies/dist /index.js 6:9-38\n\xc2\xa0@ ./node_modules/web3-providers-http/lib/index.js 25:11-49\n\xc2\xa0@ ./node_modules/web3-core -requestmanager/lib/index.js 46:18-48\n\xc2\xa0@ ./node_modules/web3-core/lib/index.js 22:23-58\n\xc2\xa0@ ./node_modules/web3 /lib/index.js 29:11-31\n\xc2\xa0@ ./src/pages/index.js 9:0-24\n\xc2\xa0@ ./.cache/ this_is_virtual_fs_path /$virtual/async -requires.js 21:11-23:5\n\xc2\xa0@ ./.cache/app.js 17:0-52 28:0-70 30:27-40 28:0-70

\n
\n
\n

webpack 编译有 10 个错误

\n
\n

我尝试手动安装这些模块,将它们添加到 package.json 等中,但没有任何效果。

\n

你能帮助我吗?

\n

wsl*_*yvh 7

不幸的是,大多数 Web3 堆栈严重依赖于窗口、浏览器和外部加密依赖项,而这些依赖项在服务器端不可用。这不仅仅是 Gatsby 的问题,其他 SSR 和静态站点生成器(例如 Next.js)也是如此。

不过,有一些解决方法。请参阅在 Gatsby 上使用仅客户端包

  1. 使用不同的库或方法

  2. 通过CDN添加客户端包

  3. 使用可加载组件加载客户端相关组件

  4. 仅在客户端使用 React.lazy 和 Suspense

根据您的要求,#1 可能不是一个选择。我使用以太坊而不是 web3 取得了更好的成功。但在某些时候您可能会遇到其他软件包的类似问题。

#2 和 3/4 的组合将是最佳选择。首先,删除导致问题的包 (web3),然后从使用它的页面/组件加载它们gatsby-browser.js或在使用react-helmet它的页面/组件上使用它们。

gatsby-browser.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")
  }
}
Run Code Online (Sandbox Code Playgroud)

反应头盔

<Helmet>
    <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/web3@latest/dist/web3.min.js" />
</Helmet>
Run Code Online (Sandbox Code Playgroud)

您现在应该能够使用 web3。请务必检查您是否正在浏览器中运行,使用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>
    )
}
Run Code Online (Sandbox Code Playgroud)

您可能仍然想惰性加载或使用可加载组件加载东西。例如

const LazyWeb3BlockNr = React.lazy(() =>
  import("../components/Web3BlockNr")
)
Run Code Online (Sandbox Code Playgroud)

并且在你的页面中

<div>
    {typeof window !== "undefined" && 
        <React.Suspense fallback={<div />}>
            <LazyWeb3BlockNr />
        </React.Suspense>
    }
</div>
Run Code Online (Sandbox Code Playgroud)

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


eth*_*th0 7

这对我有用。将以下内容添加到您的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
            },
        },
    })
}
Run Code Online (Sandbox Code Playgroud)