当我尝试 运行 yarn build in next.js 时出现错误

I get an error when I try to run yarn build in next.js

我正在尝试使用 yarn build 命令构建我的 next.js 项目,但我总是收到此错误:

Error: Export encountered errors on following paths:
        /settings
    at D:\web3\futnft\frontend\node_modules\next\dist\export\index.js:498:19
    at runMicrotasks (<anonymous>)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async Span.traceAsyncFn (D:\web3\futnft\frontend\node_modules\next\dist\trace\trace.js:75:20)
    at async D:\web3\futnft\frontend\node_modules\next\dist\build\index.js:1024:17
    at async Span.traceAsyncFn (D:\web3\futnft\frontend\node_modules\next\dist\trace\trace.js:75:20)
    at async D:\web3\futnft\frontend\node_modules\next\dist\build\index.js:898:13
    at async Span.traceAsyncFn (D:\web3\futnft\frontend\node_modules\next\dist\trace\trace.js:75:20)
    at async Object.build [as default] (D:\web3\futnft\frontend\node_modules\next\dist\build\index.js:82:25

这是我在 pages/settings 下的 index.tsx 文件:

import { ethers } from "ethers";
import { NextPage } from "next";
import React from "react";
import { Settings as SettingsComponent } from "../../components/Settings";

interface Props {
  setLoader: (loader: boolean) => void;
  futNFTTraining: ethers.Contract;
  futNFTMatch: ethers.Contract;
}

const Settings: NextPage<Props> = ({
  setLoader,
  futNFTMatch,
  futNFTTraining,
}) => {
  return (
    <SettingsComponent
      setLoader={setLoader}
      futNFTMatch={futNFTMatch}
      futNFTTraining={futNFTTraining}
    />
  );
};

export default Settings;

这是components/下的Settings.tsx文件:

import { ethers } from "ethers";
import Link from "next/link";
import React, { useState } from "react";
import settingsStyles from "../styles/Settings.module.scss";

interface Props {
  setLoader: (loader: boolean) => void;
  futNFTTraining: ethers.Contract;
  futNFTMatch: ethers.Contract;
}

export const Settings: React.FunctionComponent<Props> = ({
  futNFTMatch,
  futNFTTraining,
  setLoader,
}) => {
  const setValue = async (setter: ethers.ContractFunction, value: any) => {
    setLoader(true);
    const tx = await setter(value);
    await tx.wait();
    setLoader(false);
  };

  const [formation, setFormation] = useState<string>("");
  const [positions, setPositions] = useState<string[]>([]);
  const [signer, _] = useState<ethers.Signer>(
    (window as any).provider.getSigner()
  );
  return (
    <div className={settingsStyles.settingsContainer}>
      <h2>Mint New NFTs</h2>
      <Link href="/mint">
        <a className={settingsStyles.link}>Mint</a>
      </Link>
      <h2>Set State Variables</h2>
      <h3>FutNFTTraining Smart Contract</h3>
      <div className={settingsStyles.item}>
        <span className={settingsStyles.variable}>cooldown</span>
        <input
          type="number"
          name="cooldown"
          id="cooldown"
          className={settingsStyles.value}
        />
        <span className={settingsStyles.unit}>seconds</span>
        <button
          className={settingsStyles.setBtn}
          onClick={async () => {
            await setValue(
              futNFTTraining.connect(signer).setCooldown,
              parseInt(
                (document.getElementById("cooldown")! as HTMLInputElement).value
              )
            );
          }}
        >
          Set
        </button>
      </div>
      <div className={settingsStyles.item}>
        <span className={settingsStyles.variable}>fee</span>
        <input
          type="number"
          name="fee"
          id="fee"
          className={settingsStyles.value}
        />
        <span className={settingsStyles.unit}>MATIC</span>
        <button
          className={settingsStyles.setBtn}
          onClick={async () => {
            await setValue(
              futNFTTraining.connect(signer).setFee,
              parseInt(
                (document.getElementById("fee")! as HTMLInputElement).value
              )
            );
          }}
        >
          Set
        </button>
      </div>
      <div className={settingsStyles.item}>
        <span className={settingsStyles.variable}>maxLevel</span>
        <input
          type="number"
          name="maxLevel"
          id="maxLevel"
          className={settingsStyles.value}
        />
        <span className={settingsStyles.unit}></span>
        <button
          className={settingsStyles.setBtn}
          onClick={async () => {
            await setValue(
              futNFTTraining.connect(signer).setMaxLevel,
              parseInt(
                (document.getElementById("maxLevel")! as HTMLInputElement).value
              )
            );
          }}
        >
          Set
        </button>
      </div>
      <h3>FutNFTMatch Smart Contract</h3>
      <div className={settingsStyles.item}>
        <span className={settingsStyles.variable}>
          levelPercentSuitablePosition
        </span>
        <input
          type="number"
          name="levelPercentSuitablePosition"
          id="levelPercentSuitablePosition"
          className={settingsStyles.value}
        />
        <span className={settingsStyles.unit}>%</span>
        <button
          className={settingsStyles.setBtn}
          onClick={async () => {
            await setValue(
              futNFTMatch.connect(signer).setLevelPercentSuitablePosition,
              parseInt(
                (
                  document.getElementById(
                    "levelPercentSuitablePosition"
                  )! as HTMLInputElement
                ).value
              )
            );
          }}
        >
          Set
        </button>
      </div>
      <div className={settingsStyles.item}>
        <span className={settingsStyles.variable}>levelPercentNoPosition</span>
        <input
          type="number"
          name="levelPercentNoPosition"
          id="levelPercentNoPosition"
          className={settingsStyles.value}
        />
        <span className={settingsStyles.unit}>%</span>
        <button
          className={settingsStyles.setBtn}
          onClick={async () => {
            await setValue(
              futNFTMatch.connect(signer).setLevelPercentNoPosition,
              parseInt(
                (
                  document.getElementById(
                    "levelPercentNoPosition"
                  )! as HTMLInputElement
                ).value
              )
            );
          }}
        >
          Set
        </button>
      </div>
      <div className={settingsStyles.item}>
        <span className={settingsStyles.variable}>lineupFee</span>
        <input
          type="number"
          name="lineupFee"
          id="lineupFee"
          className={settingsStyles.value}
        />
        <span className={settingsStyles.unit}>MATIC</span>
        <button
          className={settingsStyles.setBtn}
          onClick={async () => {
            await setValue(
              futNFTMatch.connect(signer).setLineupFee,
              parseInt(
                (document.getElementById("lineupFee")! as HTMLInputElement)
                  .value
              )
            );
          }}
        >
          Set
        </button>
      </div>
      <div className={settingsStyles.item}>
        <span className={settingsStyles.variable}>matchFee</span>
        <input
          type="number"
          name="matchFee"
          id="matchFee"
          className={settingsStyles.value}
        />
        <span className={settingsStyles.unit}>MATIC</span>
        <button
          className={settingsStyles.setBtn}
          onClick={async () => {
            await setValue(
              futNFTMatch.connect(signer).setMatchFee,
              parseInt(
                (document.getElementById("matchFee")! as HTMLInputElement).value
              )
            );
          }}
        >
          Set
        </button>
      </div>
      <div className={settingsStyles.formation}>
        <h4>Add Formation</h4>
        <input
          type="text"
          name="formationName"
          id="formationName"
          placeholder="Formation Name"
          onChange={() => {
            const formationName = (
              document.getElementById("formationName")! as HTMLInputElement
            ).value;
            setFormation(formationName);
            if (formationName.length == 0) {
              setPositions([]);
            }
          }}
        />
        {formation.length > 0 && (
          <>
            <div>
              <input
                type="text"
                name="position"
                id="position"
                placeholder="Position"
              />
              <button
                onClick={() => {
                  const position = (
                    document.getElementById("position")! as HTMLInputElement
                  ).value;
                  if (position.length > 0 && positions.length < 11) {
                    const newArr = positions;
                    newArr.push(position);
                    setPositions(newArr);
                  }
                }}
              >
                Add Position
              </button>
            </div>
            <div className={settingsStyles.positions}>
              {positions.map((position, key) => {
                return (
                  <div className={settingsStyles.position} key={key}>
                    <p>{position}</p>
                    <button
                      onClick={() => {
                        const index = positions.indexOf(position);
                        const newArr = positions;
                        newArr.splice(index, 1);
                        setPositions(newArr);
                      }}
                    >
                      ✗
                    </button>
                  </div>
                );
              })}
            </div>
            {positions.length == 11 && <button>Add Formation</button>}
          </>
        )}
      </div>
    </div>
  );
};

export default Settings;

我发现了另一个具有相同问题的 Stack Overflow 问题,但无法解决我的问题。我尝试了很多删除无用道具的方法,但没有用。

当您运行此代码时,您的设置组件中是否定义了window?由于 Next.js pre-renders 页面 server-side 在发送给客户端之前,它可能不可用。因此,您可能需要在 useEffect 挂钩中执行该逻辑才能在浏览器中执行它。

我在尝试从 localStorage 访问值时遇到了类似的问题。