You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ReactJS中使用ethers库获取钱包余额时出现编译错误求助

React项目使用ethers连接Metamask时出现编译错误

问题描述

在ReactJS项目中通过NPM安装ethers库后,尝试获取Metamask钱包余额时触发编译错误,访问本地服务时收到以下错误日志:

Compiled with problems:X

ERROR in ./node_modules/node-gyp-build/node-gyp-build.js 1:9-22

Module not found: Error: Can't resolve 'fs' in '/Users/gustavopayano/Desktop/navbar/node_modules/node-gyp-build'

ERROR in ./node_modules/node-gyp-build/node-gyp-build.js 2:11-26

Module not found: Error: Can't resolve 'path' in '/Users/gustavopayano/Desktop/navbar/node_modules/node-gyp-build'

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

Module not found: Error: Can't resolve 'os' in '/Users/gustavopayano/Desktop/navbar/node_modules/node-gyp-build'

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 }

组件代码

import { React, useState } from "react";
import "./App";
import Navbar from "./Navbar";
import "./css/Metamask.css";

function Metamask() {
  const [errorMessage, setErrorMessage] = useState(null);
  const [defaultAccount, setDefaultAccount] = useState(null);
  const [userBalance, setUserBalance] = useState(null);

  const ethers = require("ethers");

  const connectWallet = () => {
    if (window.ethereum) {
      window.ethereum
        .request({ method: "eth_requestAccounts" })
        .then((result) => {
          accountChanged(result[0]);
        });
    } else {
      setErrorMessage("Install MetaMask Please!");
    }
  };

  const accountChanged = (accountName) => {
    setDefaultAccount(accountName);
    getUserBalance(accountName);
  };

  const getUserBalance = (accountAddress) => {
    window.ethereum
      .request({
        method: "eth_getBalance",
        params: [String(accountAddress), "latest"],
      })
      .then((balance) => {
        setUserBalance(ethers.utils.formatEther(balance));
      });
  };

  return (
    <div className="metamask">
      <Navbar />
      <h1>Metamask Wallet Connection</h1>
      <button class="btn btn-secondary btn-md" onClick={connectWallet}>
        {" "}
        Connect Metamask
      </button>
      <h3>Address: {defaultAccount}</h3>
      <h3>Balance: {userBalance}</h3>

      {errorMessage}
    </div>
  );
}

export default Metamask;

解决方案

方案一:仅引入ethers浏览器兼容的核心工具(推荐)

你的代码只用到了ethers的formatEther工具函数,无需引入完整的ethers包(包含Node.js环境依赖)。修改导入方式即可解决问题:

  1. 替换原有的const ethers = require("ethers");为:
import { utils } from "ethers";
  1. 在getUserBalance函数中,将ethers.utils.formatEther(balance)改为utils.formatEther(balance)。

方案二:配置Webpack的Node核心模块Polyfill(若需完整ethers功能)

如果需要使用ethers的完整功能(如创建Provider等),需手动配置Webpack的fallback:

  1. 安装所需的polyfill包:
npm install path-browserify os-browserify --save-dev

针对Create React App项目

CRA默认不允许修改Webpack配置,需借助react-app-rewired:

  • 安装react-app-rewired:
npm install react-app-rewired --save-dev
  • 在项目根目录创建config-overrides.js文件,添加以下配置:
module.exports = function override(config, env) {
  config.resolve.fallback = {
    ...config.resolve.fallback,
    "fs": false, // 浏览器环境无需fs模块,直接禁用
    "path": require.resolve("path-browserify"),
    "os": require.resolve("os-browserify/browser")
  };
  return config;
};
  • 修改package.json中的scripts命令:
"scripts": {
  "start": "react-app-rewired start",
  "build": "react-app-rewired build",
  "test": "react-app-rewired test"
}

针对自定义Webpack配置的项目

直接在webpack.config.js中添加resolve.fallback配置:

module.exports = {
  // ...其他Webpack配置
  resolve: {
    fallback: {
      "fs": false,
      "path": require.resolve("path-browserify"),
      "os": require.resolve("os-browserify/browser")
    }
  }
};

额外优化点

  • React中需使用className替代class,将按钮的class="btn..."改为className="btn...";
  • 错误信息可增加条件渲染和样式,例如:{errorMessage && <p style={{color: 'red'}}>{errorMessage}</p>}。

内容的提问来源于stack exchange,提问作者Gustavo Payano

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 10:30:42