在CRACO项目中使用Rust构建的WASM模块出现导入错误如何解决
错误根因
这个报错本质是CRA默认的webpack wasm加载规则,和wasm-pack --target bundler模式输出的包不兼容,导致wasm内部导出的结构体内存释放符号没有被正确识别。
解决步骤
- 首先安装wasm加载依赖:
npm install wasm-loader --save-dev
- 更新CRACO配置,禁用CRA默认的wasm处理逻辑,新增自定义加载规则,
craco.config.js配置如下:
module.exports = { webpack: { configure: (webpackConfig) => { // 移除默认的wasm扩展名解析规则 const wasmExtPos = webpackConfig.resolve.extensions.indexOf('.wasm') if (wasmExtPos >= 0) webpackConfig.resolve.extensions.splice(wasmExtPos, 1) // 修改默认loader规则 webpackConfig.module.rules.forEach(rule => { if (Array.isArray(rule.oneOf)) { // 给默认的资源加载规则排除wasm格式 rule.oneOf.at(-1).exclude.push(/\.wasm$/) // 新增wasm专属加载规则 rule.oneOf.unshift({ test: /\.wasm$/, type: 'javascript/auto', loader: 'wasm-loader' }) } }) return webpackConfig } } }
- 调整wasm模块导入逻辑:bundler模式输出的wasm包必须先完成异步初始化才能使用导出的结构体,禁止同步导入直接使用,参考写法:
// 全局存储导出的结构体 let MyStruct = null // 初始化wasm模块 const initWasmModule = async () => { const pkg = await import('@my_scope/my_pkg') // 必须先调用默认导出的初始化方法加载wasm资源 await pkg.default() MyStruct = pkg.MyStruct // 初始化完成后再执行业务逻辑,比如渲染依赖该结构体的组件 renderApp() } initWasmModule()
- 检查wasm包构建配置:
- 构建wasm包时必须使用bundler目标:
wasm-pack build --target bundler --release - 确保Rust项目中
Cargo.toml依赖的wasm-bindgen版本,和npm包中依赖的wasm-bindgen版本完全一致,版本不一致会导致导出符号不匹配的错误 - 确认Rust代码中的结构体已经正确添加
#[wasm_bindgen]注解,对外暴露的方法也添加了对应注解
- 构建wasm包时必须使用bundler目标:
内容的提问来源于stack exchange,提问作者Andrew Schoen
相关产品推荐
相关产品推荐

