Next.js+TypeScript项目Bun构建时ESM/CJS模块混用报错求助
解决Next.js+TypeScript项目中@solana/wallet-adapter编译兼容问题
针对你遇到的bun run build时CJS与ESM模块不兼容、以及动态导入导致React组件异步错误的问题,提供以下几个可行方案:
方案一:将项目切换为ESM模块
- 在项目根目录的
package.json中添加"type": "module"字段:{ "name": "your-project", "type": "module", // 其他配置... } - 处理CommonJS格式的配置文件:如果项目中有
next.config.js,将其重命名为next.config.mjs,并把文件内的require语法改为import,示例:// 修改后的next.config.mjs export const nextConfig = { /* 你的原有配置 */ }; - 重新执行
bun run build验证问题是否解决。
方案二:使用Next.js官方动态导入(next/dynamic)
React组件不能是异步函数,直接在_app.tsx中用await会导致参数解构错误。改用Next.js的dynamic函数实现客户端侧动态导入,同时禁用SSR(钱包功能仅能在客户端运行):
步骤1:拆分客户端组件
将使用钱包hooks的代码拆分为独立的客户端组件(Next.js 13+需添加'use client'标记):
// src/components/WalletConnector.tsx 'use client'; import { useWallet } from '@solana/wallet-adapter-react'; import { useWalletModal } from '@solana/wallet-adapter-react-ui'; export default function WalletConnector() { const wallet = useWallet(); const { open } = useWalletModal(); return ( <button onClick={open} disabled={wallet.connected}> {wallet.connected ? `Connected: ${wallet.publicKey?.toBase58()}` : 'Connect Wallet'} </button> ); }
步骤2:动态导入组件
在页面或布局文件中,用dynamic导入上述组件并禁用SSR:
// src/pages/index.tsx import dynamic from 'next/dynamic'; // 动态导入钱包组件,禁用SSR const WalletConnector = dynamic(() => import('../components/WalletConnector'), { ssr: false }); export default function Home() { return ( <div className="container"> <h1>Solana Wallet Demo</h1> <WalletConnector /> </div> ); }
步骤3:处理_app.tsx中的Provider
如果需要在_app.tsx中添加钱包的Provider,同样用动态导入:
// src/pages/_app.tsx import type { AppProps } from 'next/app'; import dynamic from 'next/dynamic'; import { clusterApiUrl } from '@solana/web3.js'; // 动态导入Provider,禁用SSR const ConnectionProvider = dynamic(() => import('@solana/wallet-adapter-react').then(mod => mod.ConnectionProvider), { ssr: false }); const WalletProvider = dynamic(() => import('@solana/wallet-adapter-react').then(mod => mod.WalletProvider), { ssr: false }); const WalletModalProvider = dynamic(() => import('@solana/wallet-adapter-react-ui').then(mod => mod.WalletModalProvider), { ssr: false }); const { PhantomWalletAdapter } = dynamic(() => import('@solana/wallet-adapter-wallets').then(mod => mod), { ssr: false }); function App({ Component, pageProps }: AppProps) { const endpoint = clusterApiUrl('devnet'); const wallets = [new PhantomWalletAdapter()]; return ( <ConnectionProvider endpoint={endpoint}> <WalletProvider wallets={wallets} autoConnect> <WalletModalProvider> <Component {...pageProps} /> </WalletModalProvider> </WalletProvider> </ConnectionProvider> ); } export default App;
方案三:升级@solana/wallet-adapter依赖
部分旧版本的钱包适配器存在ESM/CJS兼容问题,升级到最新版本可能直接解决:
bun update @solana/wallet-adapter-react @solana/wallet-adapter-react-ui @solana/wallet-adapter-base @solana/wallet-adapter-wallets
升级后重新执行bun run build验证。
方案四:调整TypeScript配置
在tsconfig.json中修改模块解析相关配置,适配Bundler的模块处理逻辑:
{ "compilerOptions": { "module": "ESNext", "moduleResolution": "bundler", "target": "ESNext", // 其他原有配置... } }
内容的提问来源于stack exchange,提问作者Seto
相关产品推荐
相关产品推荐

