NextJS应用导入web3时Netlify构建报错:Can't resolve 'electron' 求助
问题根因
你遇到的报错来自两方面:
- 你使用的旧版
web3.js依赖swarm-js,后者依赖的旧版got库把electron列为可选依赖,而Next.js服务端构建时webpack会严格检查所有依赖,未安装electron就会直接抛出构建失败错误。 - 你的web3实例直接在顶层文件导出、页面顶层导入,不管是服务端构建阶段还是客户端加载阶段都会执行初始化逻辑,额外触发了服务端不存在的客户端依赖加载。同时你的
getServerSideProps返回值不符合Next.js规范,也会导致额外的运行时错误。
解决方案
方案一(优先推荐):升级web3到4.x版本
新版web3.js已经完全重构了依赖链,移除了swarm-js和旧版got依赖,从根源上解决了electron缺失的问题,直接执行以下命令升级即可:
npm install web3@latest
方案二:适配现有版本的webpack配置
如果不想升级web3版本,可以在项目根目录的next.config.js中添加以下配置,告诉webpack忽略服务端不存在的依赖:
/** @type {import('next').NextConfig} */ const nextConfig = { webpack: (config, { isServer }) => { // 客户端构建时忽略Node原生模块和electron依赖 if (!isServer) { config.resolve.fallback = { ...config.resolve.fallback, electron: false, fs: false, net: false, tls: false, } } return config }, } module.exports = nextConfig
后续优化修改
- 修改web3实例导出逻辑,不要直接导出初始化完成的实例,改为导出懒加载函数,避免顶层导入触发不必要的初始化:
import Web3 from "web3"; const getWeb3 = () => { if (typeof window !== "undefined" && typeof window.ethereum !== "undefined") { window.ethereum.request({ method: "eth_requestAccounts" }); return new Web3(window.ethereum); } else { const provider = new Web3.providers.HttpProvider( "https://mainnet.infura.io/v3/{替换为你的INFURA_KEY}" ); return new Web3(provider); } } export default getWeb3;
- 修复
getServerSideProps的返回值规范,Next.js要求必须返回带props字段的对象,且合约实例属于不可序列化的类实例,不能直接传给前端,需要提前调用合约方法取到纯数据再返回:
import getWeb3 from '../ethereum/web3' const compiledFaucet = require('../ethereum/contracts/Faucet.json') export async function getServerSideProps(ctx) { const web3 = getWeb3() const faucetContract = new web3.eth.Contract( compiledFaucet.abi, "0x4099E633A607F6ED211e2c82565003d6F755e75e" ) // 示例:提前读取你需要的合约数据 const totalSupply = await faucetContract.methods.totalSupply().call() return { props: { totalSupply } } }
- 客户端如果需要用到web3实例,不要在顶层导入,在
useEffect回调中调用getWeb3()获取即可。
内容的提问来源于stack exchange,提问作者jspru
相关产品推荐
相关产品推荐

