Rust 开发 WebAssembly 一眼案例

用 Rust 开发 WebAssembly 并让 JS 调用,核心在于利用 wasm-bindgen 工具链来处理类型转换和内存管理。虽然底层涉及编译原理,但借助官方脚手架,实际操作非常简单,主要分为环境准备、代码编写、编译打包和 JS 调用这几个步骤。

以下是完整的实战演示流程:

🛠️ 环境准备

在开始之前,请确保你已经安装了 Rust 和 wasm-pack

  1. 安装 Rust (如果尚未安装):

    bash 复制代码
    curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
  2. 安装 wasm-pack (官方推荐的构建工具):

    bash 复制代码
    cargo 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 在浏览器中运行。

相关推荐
低保和光头哪个先来2 小时前
TinyEditor 篇1:实现工具栏按钮向服务器上传图片
服务器·开发语言·前端·javascript·vue.js·前端框架
忡黑梨2 小时前
BUUCTF_reverse_[MRCTF2020]Transform
c语言·开发语言·数据结构·python·算法·网络安全
于先生吖2 小时前
Java 同城服务同城租房系统源码 完整项目实现
java·开发语言
echome8882 小时前
Go 语言并发编程:sync.WaitGroup 实战指南
开发语言·golang·xcode
一匹电信狗2 小时前
【LeetCode面试题17.04】消失的数字
c语言·开发语言·数据结构·c++·算法·leetcode·stl
j_xxx404_2 小时前
从 O(N) 到 O(log N):LCR 173 点名问题的五种解法与最优推导
开发语言·c++·算法
仰泳的熊猫2 小时前
题目2265:蓝桥杯2015年第六届真题-移动距离
开发语言·数据结构·c++·算法·蓝桥杯
共享家95272 小时前
Java入门
java·开发语言
小曹要微笑2 小时前
C#中什么是类
开发语言·c#·面向对象·
星辰_mya2 小时前
ThreadLocal 与内存泄漏
java·开发语言