TypeError: path.resolve is not a function

TypeError: path.resolve is not a function

我在 Udemy 上完成了一个使用 solc@^0.4.17、React 和 Next.js 的以太坊智能合约课程。我认为尝试将所有内容升级到最新版本并尝试重构会是一个有趣的练习。我在一个名为 factory.js 的文件中有以下代码被导入到我的主索引文件中:

import web3 from './web3';
const path = require('path');
const fs = require('fs');

const abiPath = path.resolve('ethereum/build', 'CampaignFactory.abi');
console.log(abiPath);

const abi = fs.readFileSync(abiPath, 'utf8');
console.log(abi);

const factory = new web3.eth.Contract(
    JSON.parse(abi),
    '0x2d54559dCe0DA6C92378A916e9eE0422CEFFCD80'
);

export default factory;

在我的主索引文件中,我这样称呼它:

import factory from '../ethereum/factory';
...
class CampaignIndex extends Component {
    static async getInitialProps() {
        const campaigns = await factory.methods.getDeployedCampaigns().call();

        return { campaigns };
    }
...

这是console.log:

    wait  - compiling /...
    event - compiled successfully in 637 ms (1422 modules)
    /Users/sonnyparlin/Github/kickstart/ethereum/build/CampaignFactory.abi
    [
      {
        "inputs": [
          {
            "internalType": "uint256",
            "name": "minimum",
            "type": "uint256"
          }
        ],
        "name": "createCampaign",
        "outputs": [],
        "stateMutability": "nonpayable",
        "type": "function"
      },
      {
        "inputs": [
          {
            "internalType": "uint256",
            "name": "",
            "type": "uint256"
          }
        ],
        "name": "deployedCampaigns",
        "outputs": [
          {
            "internalType": "address",
            "name": "",
            "type": "address"
          }
        ],
        "stateMutability": "view",
        "type": "function"
      },
      {
        "inputs": [],
        "name": "getDeployedCampaigns",
        "outputs": [
          {
            "internalType": "address[]",
            "name": "",
            "type": "address[]"
          }
        ],
        "stateMutability": "view",
        "type": "function"
      }
    ]

控制台日志确认 path.resolve() 确实在工作,但是当我通过网络浏览器转到该页面时,我看到以下错误:

Call Stack
Module../ethereum/factory.js
file:///Users/sonnyparlin/Github/kickstart/.next/static/chunks/pages/index.js (1148:1)
Module.options.factory
/_next/static/chunks/webpack.js (638:31)
__webpack_require__
file:///Users/sonnyparlin/Github/kickstart/.next/static/chunks/webpack.js (37:33)
fn
/_next/static/chunks/webpack.js (307:21)
eval
webpack-internal:///./pages/index.js (9:75)
Module../pages/index.js
file:///Users/sonnyparlin/Github/kickstart/.next/static/chunks/pages/index.js (1192:1)
Module.options.factory
/_next/static/chunks/webpack.js (638:31)
__webpack_require__
file:///Users/sonnyparlin/Github/kickstart/.next/static/chunks/webpack.js (37:33)
fn
/_next/static/chunks/webpack.js (307:21)
eval
node_modules/next/dist/build/webpack/loaders/next-client-pages-loader.js?page=%2F&absolutePagePath=%2FUsers%2Fsonnyparlin%2FGithub%2Fkickstart%2Fpages%2Findex.js! (5:15)
eval
node_modules/next/dist/client/route-loader.js (236:50)

我的猜测是这确实是某种版本控制或依赖性问题,所以我也包括了我的 package.json 文件:

{
  "name": "kickstart",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "mocha",
    "dev": "node server.js"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@truffle/hdwallet-provider": "^1.0.37",
    "fs-extra": "^10.0.0",
    "ganache-cli": "^6.1.8",
    "mocha": "^9.1.3",
    "next": "^12.0.3",
    "next-routes": "^1.4.2",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "semantic-ui-css": "^2.4.1",
    "semantic-ui-react": "^2.0.4",
    "solc": "^0.8.9",
    "web3": "^1.6.0"
  },
  "browser": {
    "fs": false,
    "path": false,
    "os": false
  }
}

以及我的项目文件列表:

当您导入 factory.js 时,接下来是 运行 整个文件,它看到“路径”并抛出错误

path用于获取合约文件目录,fs用于读取合约文件。然后用 solc 编译器编译这段代码,你 运行 这个文件用

  node fileName.js

根据您使用 solc 定义的指令,此编译将创建一个包含“abi”属性 的 .json 文件。到目前为止,我们与 next.js.

没有任何关系

然后,将其重构为一个单独的文件:

import abi from "directory/file.json"

const factory = new web3.eth.Contract(
    // pass the abi
    JSON.parse(abi),
    '0x2d54559dCe0DA6C92378A916e9eE0422CEFFCD80'
);

现在您必须将其导入到您的 next.js 项目中。