WebAssembly
Rslib 支持遵循 WebAssembly ESM Integration 提案语法使用的 WebAssembly(.wasm)模块。
使用 WebAssembly ESM Integration 提案语法的源码仅能构建为 ESM 产物,因此 format 须为 'esm'(默认值)。
这是因为 .wasm 模块的编译和实例化是异步的,静态导入它的 JavaScript 模块也会成为 async module,并将异步求值传播到上游模块图。CommonJS、UMD 和 IIFE 没有与 ESM async module 等价的模块求值和导出语义,因此无法可靠地转换这类导入。
在 JavaScript 中导入 wasm
你可以使用 ESM 模块导入语法导入 .wasm 模块:
Rslib 支持以下几种 .wasm 模块的导入形式。
静态导入与导出
通过标准的 ESM 绑定访问实例化后的导出:
动态导入
Source phase 导入
import source 是 WebAssembly ESM Integration 的一部分,Rspack 对此提供了一流的支持。它导入的是编译后的 WebAssembly.Module,而不是实例化后的导出,可以让你使用自定义 import object 手动完成实例化:
也支持通过 import.source() 进行动态 source phase 导入:
TypeScript 目前不解析 import source 与 import.source()。请将 source phase 导入写在 JavaScript 文件中,或使用支持该语法的工具链。
配置产物
Rslib 提供两种 .wasm 模块的产物形态,通过 lib.wasm.mode 控制。
- Compile 模式:Rspack 在构建时处理
.wasm导入,生成加载和实例化 WebAssembly 的 JavaScript 运行时代码,并将二进制文件作为静态资源输出。消费方无需支持 ESM Integration。 - Preserve 模式:在 bundleless 构建中,Rslib 会在 JavaScript 产物中保留
.wasmESM Integration 导入,并原样输出二进制文件。下游构建工具或运行时负责解析和加载.wasm模块。
默认值取决于 bundle:
如果产物需要被浏览器等 JavaScript 运行时直接消费,你应该使用 Compile 模式。如果 bundleless 产物会交给支持 ESM Integration 的构建工具(如 Rsbuild)继续处理,或目标运行时(如 Node.js ^22.19.0 || >=24.5.0)原生支持该特性,你可以使用 Preserve 模式。Rslib 不支持同时设置 bundle: true 与 wasm.mode: 'preserve';bundle 产物请使用 Compile 模式。
Compile mode
在 Compile 模式下,Rspack 会解析 .wasm 模块,并生成负责加载和实例化 WebAssembly 的 JavaScript 胶水代码。
二进制文件会作为资源输出到 output.distPath.wasm(默认 static/wasm),并使用带 content hash 的文件名:
生成的加载运行时由 output.target 决定:
webtarget 会通过fetch加载.wasm。nodetarget 会通过 Node.js 的异步文件系统 API 加载.wasm。
Preserve mode
Preserve 模式要求 bundle 为 false。Rslib 不会生成任何 WebAssembly 加载运行时,而是在产物 JavaScript 中保留真实的 .wasm import,并将二进制文件原样输出。
.wasm 文件按源码相对路径和原文件名 copy 到产物目录:
Preserve 模式下的 .wasm 文件名不受 output.filenameHash 影响。
Rslib 会更新 JavaScript 中的 import,使其继续指向输出后的 .wasm 文件,包括通过 output.filename.js 将 JavaScript 输出到其他目录的情况。但是,WebAssembly 二进制会保持原样。如果它会反向导入 JavaScript,这些 import 仍会使用原有的相对路径和文件名。此时请勿在产物中移动或重命名被导入的 JavaScript 文件。例如,将 index.js 改为 js/index.js 或 index.mjs,会导致 WebAssembly 内部的 ./index.js import 失效。
使用 wasm-bindgen
wasm-bindgen 是使用 Rust 构建 WebAssembly 库的工具,可通过 --target 选项生成面向不同运行环境的产物。
Rslib 支持以下 target:
bundler
JavaScript 胶水以 ES module 形式导入 .wasm 文件,.wasm 模块又反向导入胶水以获得 imports 对象。由于存在这种双向相对依赖,Preserve 模式要求产物保持 .wasm 文件与 JavaScript 胶水之间的相对路径和文件名。尤其需要避免通过 output.filename.js 移动胶水,或通过 autoExtension 修改其扩展名。
module
JavaScript 胶水通过 source phase 导入语法导入 .wasm 文件,并完全在 JavaScript 中构造 imports 对象。bundle 产物请使用 Compile 模式,bundleless 产物可以使用 Preserve 模式。
web / experimental-nodejs-module
JavaScript 胶水通过 new URL('./pkg.wasm', import.meta.url) 加载 .wasm 文件。Rslib 将其作为静态资源处理,而不是 WebAssembly ESM 模块。
此时 wasm.mode 不适用。
类型声明
TypeScript 未内置 .wasm 文件的模块声明。使用 TypeScript 时,你需要在 .wasm 文件旁添加一个 .d.wasm.ts 声明文件,并在 tsconfig.json 中启用 allowArbitraryExtensions:
