【Rust】WASM 编译使用方法
最近比较好奇 Rust 编写 Web 前端
假设你已经安装了 Cargo 和 Nodejs
安装
openssl
Ubuntu
1
2sudo apt install libssl-dev
sudo apt install pkg-configWindows
安装
vcpkg
1
2
3
4
5
6# 建议安装到用户目录下
cd $HOME
# 拉取源代码
git clone https://github.com/microsoft/vcpkg
# 运行脚本
.\vcpkg\bootstrap-vcpkg.bat安装
openssl
1
2
3
4
5
6# 我们假设你是按上面的命令执行的安装
cd $HOME
# 使用命令安装64位openssl
.\vcpkg\vcpkg install openssl:x64-windows-static
# 查看安装目录
ls .\vcpkg\packages安装根证书
1
2
3
4
5
6
7
8# 我们假设你是按上面的命令执行的安装
cd $HOME
# 创建用于存放根证书的文件夹
mkdir .\certs
# 打开文件夹
cd .\certs
# 自动下载
wget https://curl.se/ca/cacert.pem -o cacert.pem若要手动安装,请参考该页面
安装
wasm-pack
它会帮助我们把我们的代码编译成 WebAssembly 并制造出正确的 npm 包
若是参考上面的方法安装的 Windows 版本的Openssl,则需要设置环境变量
设置
OPENSSL_NO_VENDOR
为1
是为了告诉 crate 使用预编译的 openssl 库1
2
3
4
5
6
7
8
9
10
11# 设置临时环境变量
set VCPKG_ROOT=$HOME\vcpkg
set OPENSSL_NO_VENDOR=1
set RUSTFLAGS=-Ctarget-feature=+crt-static
set SSL_CERT_FILE=$HOME\certs\cacert.pem
# 我在Win11上使用上面的命令设置未生效,特使用以下命令设置永久变量,然后重启终端生效
setx VCPKG_ROOT $HOME\vcpkg
setx OPENSSL_NO_VENDOR 1
setx RUSTFLAGS -Ctarget-feature=+crt-static
setx SSL_CERT_FILE $HOME\certs\cacert.pem然后安装它
1
cargo install wasm-pack
尝试编译一下
Plotters
的 WASM 例子这是个跨平台的 Rust 图标库,同样可以运行在浏览器上
1
2
3
4
5
6# 拉取代码
git clone --recurse-submodules https://github.com/plotters-rs/plotters.git
# 运行 WASM 的例程(务必进到文件夹中去运行脚本)
cd .\plotters\examples\wasm-demo
.\start-server.bat完成后保持终端运行,然后访问
http://localhost:8080/
就可以看到页面了接下来我们自己创建一个工程实现在网页上绘制动态图表的功能,其实主要就是想看看这个库用了 WASM 有多快
okk,那我们先创建一个工程用于生成 wasm 的文件
1
cargo new --lib chart-wasm
然后使用 VSCode 打开这个文件夹
1
code .\chart-wasm
编辑
Cargo.toml
1
2
3
4
5
6
7
8
9
10
11
12
13[package]
name = "chart-wasm"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib]
crate-type = ["cdylib"]
[dependencies]
wasm-bindgen = "0.2"crate-type = ["cdylib"]
用于生成一个动态链接库,特定于平台的,我们这里将生成.wasm
的动态链接库编辑
./src/lib.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20// 声明使用了外部库 wasm_bindgen
extern crate wasm_bindgen;
// 引入 wasm_bindgen::prelude 的所有模块
use wasm_bindgen::prelude::*;
// 设置 wasm_bindgen 属性告诉编译器如何引入下面extern里的函数
extern "C" {
// 声明 Javascript 里的 alert 函数,传入类型是字符串
pub fn alert(s: &str);
}
// 设置 wasm_bindgen 属性告诉编译器需要将这个函数导出
pub fn rust_alert(name: &str) {
// 调用上面声明的 alert 函数像浏览器发送一个通知
// 使用 format 宏可以格式化字符串,这里等于 "Hello, " + name + "!"
alert(&format!("Hello, {}!", name));
}编译
1
2
3
4# 为 Rust 添加新的编译器
rustup target add wasm32-unknown-unknown
# 打包当前库为 WASM
wasm-pack build --release --target webok,最后打包的文件都在
./pkg
目录下需要说明的是这里我们没有对包的体积进行压缩
使用它,这里使用的是
webpack
(这个方法暂时不能使用)创建站点工作目录
1
2
3
4
5
6# 离开 Rust 工程
cd ..
# 创建站点工程文件夹
mkdir site
# 使用 VSCode 打开这个文件夹
code .\site创建一个
package.json
文件,chart-wasm
的路径是 Rust 工程生成的pkg
目录的路径1
2
3
4
5
6
7
8
9
10
11
12
13{
"scripts": {
"serve": "webpack-dev-server"
},
"dependencies": {
"chart-wasm": "file:../chart-wasm/pkg"
},
"devDependencies": {
"webpack": "^4.25.1",
"webpack-cli": "^3.1.2",
"webpack-dev-server": "^3.1.10"
}
}创建
webpack.config
1
2
3
4
5
6
7
8
9const path = require('path');
module.exports = {
entry: "./index.js",
output: {
path: path.resolve(__dirname, "dist"),
filename: "index.js",
},
mode: "development"
};然后我们需要创建一个
src/index.js
,里面调用了 Rust 工程定义的rust_alert
函数并传入了个字符串 “Rust
“1
2
3
4
5
6
7
8import init from '../node_modules/chart-wasm/chart_wasm.js';
import {rust_alert} from '../node_modules/chart-wasm/chart_wasm.js';
function run() {
rust_alert("Rust");
}
init().then(run)然后再创建一个
src/index.html
1
2
3
4
5
6
7
8
9
10
<html>
<head>
<meta charset="utf-8">
<title>wasm example</title>
</head>
<body>
<script type="module" src="./index.js"></script>
</body>
</html>到此还不能直接运行,因为 webpack 提供的开箱即用的加载器不能识别 wasm,还需要定义一个加载器,打开
webpack.config.js
在
module.exports = {
里面再添加1
2
3module: {
rules: [{ test: /\.wasm$/, use: 'wasm-loader' }],
},另外 webpack5 添加了支持 wasm 的实验性功能
运行
1
2
3
4
5
6# 安装依赖包
# 这还会将 Rust 工程中的 pkg 文件夹里的内容链接到 node_modules 文件夹中去
npm install
# 运行服务器
npm run serve使用浏览器访问
localhost:8080
在 Vue 中使用它
使用脚手架创建 vue 工程
1
【Rust】WASM 编译使用方法