在学rust,以及在讨论rust的未来应用领域的时候,有一个词一直在眼前蹦跶(WASM),所以什么是WASM?

前言

Google:WASM(WebAssembly)是一个可移植、体积小、加载快并且兼容 Web 的全新格式。

简单来说就是在浏览器上直接运行字节码,而不是js脚本。一拍大腿,好东西啊,把js替代,然后性能蹭蹭蹭往上涨就完了。仔细一想,好像有哪里不对劲,比如Python一直被诟病性能差,但是任然无法阻挡它的受欢迎程度,也没有任何被rust替代的迹象。同理,现如今在Google的优化下,js的性能应付现在的环境已经绰绰有余了,那么WASM的出现是不是多此一举呢?

事实好像不是这样的,普通场景下js的性能已经足够,但是在一些特殊场景下,比如游戏、图形、音频、视频等,js的性能就显得捉襟见肘了。所以WASM的出现就是为了解决这些问题的。WASM并不是为了替代js而是对js的补充。

而且WASM非常便携,运行在:所有主要的Web浏览器、V8运行时(如 Node.js)和独立的wasm运行时(如Wasmtime、Lucet和Wasmer)。

WASM可以导出函数和常量,并且在js的上下文中,可以和Wasm同步访问。

环境准备

0.安装rust,参考https://www.luodeb.top/cf04606/

1.安装wasm-pack

1
cargo install wasm-pack

记得添加环境变量~/.cargo/binPATH中。

创建项目

0.随便找个文件夹,然后cargo init

Cargo.toml
1
2
3
4
5
6
7
8
9
10
[package]
name = "wasm"
version = "0.1.0"
edition = "2021"

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

[dependencies]
wasm-bindgen = "0.2.92"

1.重命名src/main.rssrc/lib.rs

src/lib.rs
1
2
3
4
5
6
7
8
9
10
11
// The wasm-pack uses wasm-bindgen to build and generate JavaScript binding file.
// Import the wasm-bindgen crate.
use wasm_bindgen::prelude::*;

// Our Add function
// wasm-pack requires "exported" functions
// to include #[wasm_bindgen]
#[wasm_bindgen]
pub fn add(a: i32, b: i32) -> i32 {
return a + b;
}

2.安装wasm-bindgen,使用命令cargo install wasm-bindgen-cli就可以了。不得不说,cargo真是太方便啦。

3.然后使用命令wasm-pack build --target web编译项目。

这一步将会生成一个pkg文件夹,里面有编译好的一大堆文件,其中重点关注一下wasm文件和js文件。

4.接下来新建一个index.js文件,用来调用wasm文件。

pkg/index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// Import our outputted wasm ES6 module
// Which, export default's, an initialization function
import init from "./pkg/hello_world.js";

const runWasm = async () => {
// Instantiate our wasm module
const helloWorld = await init("./pkg/hello_world_bg.wasm");

// Call the Add function export from wasm, save the result
const addResult = helloWorld.add(24, 24);

// Set the result onto the body
document.body.textContent = `Hello World! addResult: ${addResult}`;
};
runWasm();

5.然后在pkg文件夹下新建一个index.html文件,用来调用js文件。

pkg/index.html
1
2
3
4
5
6
7
8
9
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Hello World - Rust</title>
<script type="module" src="./index.js"></script>
</head>
<body></body>
</html>

6.因为wasm文件是二进制文件,所以需要一个服务器来运行,我这里使用python自带的http服务器来运行吧。一行命令python -m http.server 8000就可以了。

打开浏览器,输入http://localhost:8000,看到Hello World! addResult: 48就成功了。
wasm-1-2024-05-12-04-28-50

后记

Rewrite Everything in Rust

当然,wasm只是rust的一个应用方向,不过大家好像也不是那么喜欢用rust来写wasm。如果有时间的话,可以尝试一下c/c++或者go来写wasm。