在NextJS应用程序中导入web3时出现Netlify构建错误 - "错误:无法解决'electron'..."



我正在构建一个使用web3与以太坊智能合约交互的网页。每当我将web3导入页面时,Netlify构建中都会出现错误:

9:54:39 PM: ModuleNotFoundError: Module not found: Error: Can't resolve 'electron' in '/opt/build/repo/node_modules/swarm-js/node_modules/got'
9:54:39 PM: > Build error occurred
9:54:39 PM: Error: > Build failed because of webpack errors

我可以通过将web3导入添加到页面来重新处理得到这个错误与没有得到它:

import web3 from '../ethereum/web3'

上面的代码只是从另一个文件中导出一个实例化的web3实例:

import Web3 from "web3";

let web3;

if (typeof window !== "undefined" && typeof window.ethereum !== "undefined") {
// We are in the browser and metamask is running.
window.ethereum.request({ method: "eth_requestAccounts" });
web3 = new Web3(window.ethereum);
} else {
// We are on the server *OR* the user is not running metamask
const provider = new Web3.providers.HttpProvider(
"https://mainnet.infura.io/v3/{INFURA_KEY}"
);
web3 = new Web3(provider);
}

export default web3;

我想这可能与web3只能在浏览器中运行和NextJS做一些SSR有关,但我不能完全指出这个问题。这是我的全页代码:

import Head from 'next/head'
import Header from '../components/Header'
import Menu from '../components/Menu'
import Footer from '../components/Footer'
import web3 from '../ethereum/web3'
const compiledFaucet = require('../ethereum/contracts/Faucet.json')

export default function Faucet() {
const getICHCHandler = () => {
console.log('dripping ICHC from faucet')
}
return (
<div className="container">
<Head>
<title>I Can Has Cheezburger Token</title>
<link rel="icon" href="/favicon.ico" />
<link rel="stylesheet" href="/fonts/fonts.css"></link>
<link href="https://unpkg.com/nes.css@latest/css/nes.min.css" rel="stylesheet" />
{/* Global site tag (gtag.js) - Google Analytics */}
<script async src="https://www.googletagmanager.com/gtag/js?id=G-2EF9PKF797"></script>
<script
dangerouslySetInnerHTML={{
__html: `
window.dataLayer = window.dataLayer || []
function gtag(){dataLayer.push(arguments)}
gtag('js', new Date())
gtag('config', 'G-2EF9PKF797')
`,
}}
/>
</Head>
<main>
<Header />
<div className="container">
<h2 className="pink">ICHC Token Faucet</h2>
<img src="/faucet_med.png" alt="ICHC Token Faucet" />
<div className="faucet-container">
<div className="nes-field">
<label htmlFor="name_field" className="input-label">Enter wallet address:</label>
<input type="text" id="name_field" className="nes-input faucet-txt-input" />
</div>

<button onClick={getICHCHandler} type="button" className="nes-btn is-primary faucet-btn">Get ICHC Token</button>
</div>
<Menu />
</div>
</main>
<Footer />
<style jsx>{`
.container {
padding: 1rem 0.5rem;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.container h2 {
font-size: 1em;
font-family: "press_start_2pregular", Times,"Times New Roman", serif;
}
.container img {
margin-top: 1em;
}
main {
padding: 0 0;
margin: 0 0 5rem 0;
flex: 1;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
}
.faucet-container {
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
width: 700px;
margin: 1em 0;
}
.input-label {
font-size: .7em;
font-family: "press_start_2pregular", Times,"Times New Roman", serif;
}
.faucet-txt-input {
width: 700px;
font-size: .9em;
font-family: "press_start_2pregular", Times,"Times New Roman", serif;
}
.faucet-btn {
margin-top: 2em;
margin-bottom: 1em;
font-size: .8em;
font-family: "press_start_2pregular", Times,"Times New Roman", serif;
color: black;
}
.faucet-btn span {
margin-left: 40px;
}

.faucet-btn:hover {
cursor: pointer;
color: #ffffff;
}
a {
color: inherit;
text-decoration: none;
}
.title a {
color: #0070f3;
text-decoration: none;
}
.title a:hover,
.title a:focus,
.title a:active {
text-decoration: underline;
}
.grid {
display: flex;
align-items: center;
justify-content: center;
flex-wrap: wrap;
max-width: 1000px;
margin-top: 1rem;
}
@media (max-width: 600px) {
.grid {
width: 100%;
flex-direction: column;
}
}
`}</style>
<style jsx global>{`
html,
body {
padding: 0;
margin: 0;
color: aqua;
font-family: Times,"Times New Roman", serif;
cursor: default !important;
}
.white {
color: #FFFFFF;
}
.pink {
color: #FF007A;
}
.default-font {
font-family: Times,"Times New Roman", serif;
}
body {
background: url("/stars_sparkle_bg.gif");
}
* {
box-sizing: border-box;
}
`}</style>
</div>
)
}
export async function getServerSideProps(ctx) {
const faucetContract = new web3.eth.Contract(
compiledFaucet.abi,
"0x4099E633A607F6ED211e2c82565003d6F755e75e"
)
return { faucetContract }
}

对于其他面临这个问题的人来说,经过大量研究,以下是最终对我有效的方法。

这似乎是一个Webpack问题,其中一个依赖项的web3依赖项中的"电子"的条件/内联导入被不适当地忽略。解决方案是明确忽略next.config.js文件中的electron,如下所示:

/**
* @type {import('next').NextConfig}
*/
const nextConfig = {
webpack: (config, { webpack }) => {
config.plugins.push(new webpack.IgnorePlugin({
resourceRegExp: /^electron$/
}),);
return config
}
}

module.exports = nextConfig

最新更新