编译Rust为WebAssembly

64 阅读2分钟

安装wasm-pack

要构建我们的包,我们需要一个额外工具 wasm-pack。它会帮助我们把我们的代码编译成 WebAssembly 并制造出正确的 npm 包。使用下面的命令可以下载并安装它

cargo install wasm-pack

创建项目

cargo new --lib mywasm

image.png

添加函数

修改src/lib.rs文件,我们添加一些函数


// wasm-bindgen 来提供 JavaScript 和 Rust 类型之间的桥梁。
// 它允许 JavaScript 使用字符串调用 Rust API,或调用 Rust 函数来捕获 JavaScript 异常。
use wasm_bindgen::prelude::*;

// 从Web的API中导入window.alert
#[wasm_bindgen]
extern "C" {
    fn alert(s: &str);
}

// 从Rust中导出greet函数给JavaScript调用
#[wasm_bindgen]
pub fn greet(name: &str) {
    alert(&format!("Hello, wasm, I'm {}", name));
}

添加好依赖

Cargo.toml中添加上wasm-bindgen这个依赖包

[package]
name = "mywasm"
version = "0.1.0"
edition = "2021"

[dependencies]
wasm-bindgen = "0.2.99"

编译

我们使用最开始安装的wasm-pack工具编译项目,执行wasm-pack build --target web命令

➜  mywasm git:(master) ✗ wasm-pack build --target web
Error: crate-type must be cdylib to compile to wasm32-unknown-unknown. Add the following to your Cargo.toml file:

[lib]
crate-type = ["cdylib", "rlib"]
Caused by: crate-type must be cdylib to compile to wasm32-unknown-unknown. Add the following to your Cargo.toml file:

[lib]
crate-type = ["cdylib", "rlib"]

可以发现有报错,按着报错信息的提示,我们修改下Cargo.toml文件

[package]
name = "mywasm"
version = "0.1.0"
edition = "2021"

[lib]
crate-type = ["cdylib", "rlib"]

[dependencies]
wasm-bindgen = "0.2.99"

再次执行命令,可以看到项目目录录下生成了一个pkg文件夹

image.png

使用wasm

在项目目录下我们创建一个html文件用来测试一下上面生成的wasm功能。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  
</body>
<script type="module">
  import init, {greet} from "./pkg/mywasm.js";  // 导入函数
  init().then(() => {
    greet("你好");  // 调用我们在rust中导出的函数
  })
</script>
</html>

使用python3 -m http.server命令开启一个web服务

➜  mywasm git:(master) ✗ python3 -m http.server
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...

浏览器打开html,可以看到如下效果。

image.png

参考文章