用 Rust 开发 WebAssembly 并让 JS 调用,核心在于利用 wasm-bindgen 工具链来处理类型转换和内存管理。虽然底层涉及编译原理,但借助官方脚手架,实际操作非常简单,主要分为环境准备、代码编写、编译打包和 JS 调用这几个步骤。
以下是完整的实战演示流程:
🛠️ 环境准备
在开始之前,请确保你已经安装了 Rust 和 wasm-pack。
-
安装 Rust (如果尚未安装):
bashcurl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -
安装
wasm-pack(官方推荐的构建工具):bashcargo install wasm-pack
🦀 步骤一:创建 Rust 项目
在终端中执行以下命令来创建一个新的库项目:
bash
cargo new --lib rust_wasm_add
cd rust_wasm_add
📦 配置 Cargo.toml
你需要引入 wasm-bindgen 依赖,它负责生成 JS 和 WASM 之间的胶水代码。
文件:Cargo.toml
toml
[package]
name = "rust_wasm_add"
version = "0.1.0"
edition = "2021"
[lib]
crate-type = ["cdylib", "rlib"] # 必须包含 cdylib 以生成 .wasm 文件
[dependencies]
wasm-bindgen = "0.2"
💻 步骤二:编写 Rust 代码
我们将编写一个简单的 add 函数,并使用 #[wasm_bindgen] 宏来标记哪些函数需要暴露给 JavaScript。
文件:src/lib.rs
rust
// 引入 wasm_bindgen 宏
use wasm_bindgen::prelude::*;
// 使用 #[wasm_bindgen] 标记该函数,使其对 JS 可见
#[wasm_bindgen]
pub fn add(a: i32, b: i32) -> i32 {
a + b
}
// 你也可以导出一个初始化函数(可选,用于调试)
#[wasm_bindgen(start)]
pub fn main() {
// 这将在 WASM 实例化时运行
// 注意:在浏览器中,console_log 需要配置,这里仅作示意
}
🏗️ 步骤三:编译为 WebAssembly
使用 wasm-pack 命令将 Rust 代码编译为 WebAssembly,并生成配套的 JavaScript 胶水代码。
在项目根目录下运行:
bash
wasm-pack build --target web --out-name wasm --out-dir ./www/pkg
参数说明:
--target web: 生成适合浏览器直接使用的 ES6 模块格式。--out-dir: 指定输出目录,这里我们输出到同级的www文件夹下,方便前端测试。
编译成功后,www/pkg 目录下会生成以下文件:
wasm.js: 胶水代码,处理内存、类型转换。wasm_bg.wasm: 核心的 WebAssembly 二进制文件。package.json: 如果需要发布到 npm 的信息。
🌐 步骤四:JavaScript 调用演示
我们在 www 目录下创建一个简单的 HTML 页面来测试。
文件:www/index.html
html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Rust + WASM Add Demo</title>
</head>
<body>
<h1>结果将显示在这里:</h1>
<div id="output"></div>
<!-- 注意:type="module" 是必须的,因为 wasm-pack 生成的是 ES6 模块 -->
<script type="module">
import init, { add } from './pkg/wasm.js';
async function run() {
// 1. 初始化 WASM 模块
// init() 会加载 .wasm 文件并准备运行时
await init();
// 2. 调用 Rust 函数
const result = add(10, 20);
// 3. 显示结果
document.getElementById('output').textContent =
`Rust 计算结果: 10 + 20 = ${result}`;
}
run();
</script>
</body>
</html>
🚀 运行效果
由于 WebAssembly 涉及跨域资源加载(.wasm 文件),你不能直接双击 index.html 打开(会报 CORS 错误)。你需要启动一个本地服务器。
在 www 目录下,你可以使用 Python 或 Node.js 启动服务器:
使用 Python 3:
bash
cd www
python -m http.server 8080
使用 Node.js (需安装 http-server):
bash
npx http-server
打开浏览器访问 http://localhost:8080,你应该会看到页面上显示:
Rust 计算结果: 10 + 20 = 30
📌 总结
- Rust 端 :使用
wasm-bindgen宏标记函数。 - 构建工具 :使用
wasm-pack build --target web。 - JS 端 :使用
import引入生成的 JS 文件,并先调用init()初始化 WASM 实例。
这样,你就成功利用 Rust 的高性能实现了加法运算,并通过 WebAssembly 在浏览器中运行。