You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 11:42:16