React引入Solana web3.js Keypair报非ESM模块导出错误
Solana React项目导入Keypair报错排查方案
问题背景
开发基于Solana链的NFT铸造React应用时,已从@solana/web3.js、@solana/spl-token引入所需依赖类,导入Keypair类时触发构建报错,相关代码与报错信息如下:
App.tsx 代码
import React from 'react'; import './App.css'; import MintToken from './mint-token'; function App() { return ( <div className="App"> <header className="App-header"> <MintToken/> </header> </div> ); } export default App;
mint-token.tsx 代码
该组件用于创建钱包、铸造代币,代码如下:
import React from 'react'; import { clusterApiUrl, Connection, PublicKey, Keypair, LAMPORTS_PER_SOL } from '@solana/web3.js'; import { createMint, getOrCreateAssociatedTokenAccount, mintTo, transfer, Account, getMint, getAccount } from '@solana/spl-token'; // 补齐浏览器环境缺失的Buffer类 window.Buffer = window.Buffer || require("buffer").Buffer; function MintToken() { const connection = new Connection(clusterApiUrl('devnet'),'confirmed'); // 建立RPC连接 const fromWallet = Keypair.generate(); let mint: PublicKey; let fromTokenAccount: Account; async function createToken(){ // 领水用于支付Gas const fromAirdropSignature = await connection.requestAirdrop(fromWallet.publicKey, LAMPORTS_PER_SOL); await connection.confirmTransaction(fromAirdropSignature); // 创建新代币 mint = await createMint( connection, fromWallet, fromWallet.publicKey, null, 9 ) console.log(`Create token: ${mint.toBase58()}`); // 原代码此处误用单引号,模板字符串需用反引号,已修正 // 获取或创建关联代币账户 fromTokenAccount = await getOrCreateAssociatedTokenAccount( connection, fromWallet, mint, fromWallet.publicKey ); console.log(`Create Token Account: ${fromTokenAccount.address.toBase58()}`); // 同上修正反引号 } return ( <div> Mint Token Section <div> <button onClick={createToken}>Create Token</button> <button>Mint Token</button> <button>Check Balance</button> <button>Send Token</button> </div> </div> ); } export default MintToken;
报错信息
./node_modules/@solana/spl-token/lib/esm/actions/createMint.mjs
Can't import the named export 'Keypair' from non EcmaScript module (only default export is available)
错误根因
该报错和代码的导入语法无关,是模块格式兼容问题:
- 高版本
@solana/spl-token采用纯ES Module(.mjs后缀)发布 - 如果使用Create React App默认脚手架,内置webpack版本默认没有开启.mjs模块的
fullySpecified兼容规则,无法正确识别跨模块的命名导出,会误判@solana/web3.js只提供默认导出,不支持Keypair这类命名导出的引用,最终抛出该错误。
可落地方案
按优先级从高到低选择即可:
- 方案1:版本降级(零代码改动,最稳定)
卸载当前高版本spl-token,安装经过CRA生态验证、兼容CommonJS的稳定版本,执行以下命令后重启开发服务即可:npm uninstall @solana/spl-token npm install @solana/spl-token@0.3.11 - 方案2:修改webpack配置(适合需要使用新版spl-token特性的场景)
如果不想降版本,通过craco或者react-app-rewired覆写CRA默认webpack配置,添加.mjs模块兼容规则:
修改完成后重启开发服务即可正常识别命名导出。// 在craco.config.js或config-overrides.js中添加如下配置 module.exports = { webpack: { configure: (webpackConfig) => { webpackConfig.module.rules.push({ test: /\.m?js/, resolve: { fullySpecified: false } }) return webpackConfig } } } - 方案3:调整导入写法(临时快速验证用)
把@solana/web3.js的命名导入改为从默认导出解构,绕开webpack的识别问题:// 替换原来的web3.js导入语句 import SolanaWeb3 from '@solana/web3.js'; const { clusterApiUrl, Connection, PublicKey, Keypair, LAMPORTS_PER_SOL } = SolanaWeb3;
内容的提问来源于stack exchange,提问作者Sahan Atulugama
相关产品推荐
相关产品推荐

