Next.js项目执行npm run build时Wasm文件报错求助
问题
在Next.js应用中使用Rust编写、经wasm-pack编译的Wasm包,执行npm run dev启动应用一切正常,但运行npm run build进行生产构建时出现两个异常:
- 抛出目标环境不支持async/await的警告
- 出现Wasm文件找不到的ENOENT错误
错误输出
> soul_dump@0.1.0 build > next build ▲ Next.js 15.3.4 ✓ Linting and checking validity of types Creating an optimized production build ... ⚠ Compiled with warnings in 8.0s ./src/wsdt/wsdt_bg.wasm The generated code contains 'async/await' because this module is using "asyncWebAssembly". However, your target environment does not appear to support 'async/await'. As a result, the code may not run as expected or may cause runtime errors. Import trace for requested module: ./src/wsdt/wsdt_bg.wasm ./src/wsdt/wsdt.js ./src/providers/notifier/notifier.tsx unhandledRejection [Error: ENOENT: no such file or directory, open '/home/wangjun/hobby/react/soul_dump/.next/server/static/wasm/7d24332e1592d207.wasm'] { type: 'Error', errno: -2, code: 'ENOENT', syscall: 'open', path: '/home/wangjun/hobby/react/soul_dump/.next/server/static/wasm/7d24332e1592d207.wasm' }
当前next.config.ts配置
import type { NextConfig } from 'next'; const nextConfig: NextConfig = { reactStrictMode: true, allowedDevOrigins: ["https://localhost:3000"], i18n: { defaultLocale: "en", locales: ["en", "zh", "ja", "it", "fr", "de", "es", "pt"], }, // Enable WebAssembly support webpack: (config, { isServer }) => { // Enable WebAssembly support config.experiments = { ...config.experiments, asyncWebAssembly: true, topLevelAwait: true, layers: true, }; // Add WebAssembly loader config.module.rules.push({ test: /\.wasm$/, type: 'webassembly/async', }); // Make sure fs module is not included in client-side bundle if (!isServer) { config.resolve.fallback = { ...(config.resolve.fallback || {}), fs: false, path: false, }; } return config; }, // Configure proper MIME types for WebAssembly files async headers() { return [ { source: '/(.*).wasm', headers: [ { key: 'Content-Type', value: 'application/wasm', }, { key: 'Cache-Control', value: 'public, max-age=31536000, immutable', }, ], }, ]; }, }; export default nextConfig;
解决方案
1. 修复Wasm文件路径缺失问题
问题根源是服务端构建时Wasm文件未被正确复制到输出目录,需调整webpack配置确保文件路径正确:
webpack: (config, { isServer }) => { config.experiments = { ...config.experiments, asyncWebAssembly: true, topLevelAwait: true, }; // 移除原有规则中对wasm文件的冲突处理 config.module.rules = config.module.rules.map(rule => { if (rule.type === 'asset/resource') { return { ...rule, exclude: [...(rule.exclude || []), /\.wasm$/], }; } return rule; }); // 统一处理wasm文件输出路径 config.module.rules.push({ test: /\.wasm$/, type: 'webassembly/async', exclude: /node_modules/, generator: { filename: 'static/wasm/[hash][ext]', }, }); // 服务端构建时禁用fs模块并确保wasm文件被正确打包 config.resolve.fallback = { ...config.resolve.fallback, fs: false, path: false, }; return config; },
2. 消除async/await环境支持警告
该警告是webpack对目标环境的误判,可通过明确指定目标环境解决:
const nextConfig: NextConfig = { // ...其他配置 webpack: (config, { isServer }) => { // ...其他webpack配置 // 明确设置编译目标 config.target = isServer ? 'node18' : 'web'; return config; }, };
也可以修改wasm-pack编译命令,生成无需async/await的同步加载模块:
wasm-pack build --target bundler --out-dir ../path/to/nextjs/src/wsdt
3. 确保Wasm模块仅在客户端加载
如果Wasm代码无需在服务端执行,避免在服务端组件中直接导入,改用客户端动态加载:
// 在notifier.tsx中替换原有导入 useEffect(() => { const loadWasm = async () => { const wsdt = await import('../../wsdt/wsdt'); // 初始化并使用Wasm模块 }; loadWasm(); }, []);
内容的提问来源于stack exchange,提问作者wangjun
相关产品推荐
相关产品推荐

