使用 wasm-pack 和 React 将 Rust 编译为 WASM
使用 wasm-pack 将 Rust 代码编译为 WebAssembly,并在 React 应用中使用生成的 JS 绑定
使用 wasm-pack 和 React 将 Rust 编译为 WASM 是 CoddyKit 上的免费 React Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 React Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 React Academy 课程共包含 4 节课。
Rust WASM 工具链
标准的 Rust 到 WASM 工作流程使用两个工具:wasm-pack 负责协调构建流程(将 Rust 编译为 WASM、运行 wasm-bindgen、生成 npm 软件包),而 wasm-bindgen 负责生成 JavaScript 绑定,使 Rust 函数能够作为普通 JavaScript 函数被调用,并正确处理类型。
wasm-bindgen 属性
#[wasm_bindgen] 属性会将 Rust 函数、结构体和方法标记为导出到 JavaScript。没有这个属性,函数虽然会被编译为 WASM,但无法从 JavaScript 访问。为函数添加 #[wasm_bindgen] 注解后,wasm-bindgen 会生成 JavaScript 胶水代码,处理参数和返回值的转换。
一个简单的 Rust 函数
一个最小的 Rust 导出函数如下:use wasm_bindgen::prelude::*; #[wasm_bindgen] pub fn add(a: u32, b: u32) -> u32 { a + b }。该函数接收两个无符号 32 位整数,并返回一个整数。wasm-bindgen 会生成 JavaScript 代码,用数字参数调用此函数,并返回数字结果。
使用 wasm-pack 构建
请在 Rust 包目录中运行 wasm-pack build --target web。该命令会将 Rust 代码编译为 WASM,运行 wasm-bindgen 生成 JavaScript 绑定,并输出一个 pkg/ 目录,其中包含 .wasm 二进制文件、JavaScript 胶水模块和 TypeScript 类型定义。
在 React 中导入
请在 React 组件中导入生成的模块:import init, { add } from '../pkg/my_lib'。init 函数负责加载并实例化 WASM 二进制文件(请在 useEffect 中调用一次)。初始化后,直接调用导出的函数:const result = add(2, 3)。
传递复杂数据:js_sys 与 JsValue
对于超出基本数值范围的复杂数据,wasm-bindgen 提供了 js_sys::Array(JavaScript 数组)、js_sys::Object(JavaScript 对象)和 wasm_bindgen::JsValue(任意 JavaScript 值)。这些类型允许 Rust 函数接收和返回 JavaScript 数组及对象,但与基本类型相比会产生更多的序列化开销。
最小化编组开销
核心性能原则是:让数据保留在 WASM 内存中,并在那里完成所有计算。只传入一次数据,完成计算后只返回最终结果。避免在每个步骤都反复跨越 WASM 边界传输数据的模式。每次跨越边界的开销虽然很小,但在密集循环中会不断累积。
使用 serde-wasm-bindgen 处理结构体
serde-wasm-bindgen 软件包支持使用 Serde 将 Rust 结构体序列化为 JavaScript 对象,以及将 JavaScript 对象反序列化为 Rust 结构体。请使用 #[derive(Serialize, Deserialize)] 为结构体添加注解,并调用 serde_wasm_bindgen::to_value() 和 from_value()。这是传递复杂结构化数据的标准方式。
在 Web Worker 中运行 WASM
长时间运行的 WASM 计算会阻塞其所在的线程。请将 WASM 放入 Web Worker 中,以便让 React 主线程保持空闲。创建一个用于初始化 WASM 模块并处理消息的 Worker 文件。通过 postMessage 向 Worker 发送数据,通过 message 事件接收结果,然后使用结果更新 React 状态。
wasm-pack 生成的 TypeScript 类型
wasm-pack 会为所有导出的函数和类型自动生成 TypeScript 声明文件(.d.ts)。这样,您的 React TypeScript 项目在调用 Rust 函数时即可获得完整的类型安全保障。生成的类型会反映 Rust 函数签名——add(a: number, b: number): number——从而让 IDE 自动补全正常工作。
生产环境注意事项
WASM 二进制文件在优化后通常为 100kb-2MB。请在 Cargo.toml 发布配置中设置 opt-level = "z",以启用 wasm-pack 构建中的 wasm-opt,从而积极优化文件大小。请使用 Content-Type: application/wasm 提供 WASM 文件,并启用 HTTP/2,以便浏览器高效地流式传输二进制文件。
wasm-bindgen 属性
Rust 代码中 #[wasm_bindgen] 属性的作用是什么?
课程回顾
wasm-pack build --target web 会将 Rust 编译为 WASM,并通过 wasm-bindgen 生成 JavaScript 绑定。请为导出的函数添加 #[wasm_bindgen] 注解。在 React 中导入 init 和导出的函数,在 useEffect 中调用 init(),然后像调用普通 JavaScript 函数一样调用这些函数。复杂结构体的序列化请使用 serde-wasm-bindgen。对于长时间运行的计算,请在 Web Worker 中运行 WASM,以便让 React 主线程保持空闲。
常见问题解答
「使用 wasm-pack 和 React 将 Rust 编译为 WASM」课时是免费的吗?
是的 — 「使用 wasm-pack 和 React 将 Rust 编译为 WASM」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 React Academy 课程的其余内容,请升级到 CoddyKit PRO。 React Academy 课程共包含 4 节课。
「使用 wasm-pack 和 React 将 Rust 编译为 WASM」这节课中我会学到什么?
使用 wasm-pack 将 Rust 代码编译为 WebAssembly,并在 React 应用中使用生成的 JS 绑定 你通过在浏览器中直接运行的动手代码来练习 React Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 React Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 React Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。
「使用 wasm-pack 和 React 将 Rust 编译为 WASM」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 React Academy 课中编写并运行代码吗?
能。每节 React Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- 什么是 WebAssembly,以及 React 如何融入其中
- 在 React 中加载 WASM 模块
- 使用 wasm-pack 和 React 将 Rust 编译为 WASM
- WASM 的应用场景:图像处理与计算