前言
需要先了解以下知识:
- WebAssembly
- Rust
- wasm_bindgen
- wasm-pack
- js-sys
- web-sys
- JavaScript
- HTML
- CSS
- webpack
假设您已经了解所有知识点,并且您的环境中已安装了 Node.js和npm 以及 Rust 的完整开发工具链(包括 rustc、cargo 和 rustup),我们现在可以进行下一步。
1. 创建项目
1.1 初始化项目
wasm-pack new demo
cd .\demo\
npm init -y
1.2 demo目录下创建index.js文件和index.html文件
<!-- path demo/index.html -->
<!DOCTYPE html>
<html><head><meta charset="utf-8" /><title>hello-wasm example</title></head><body></body>
</html>
// path demo/index.js
// empty
2. 配置webpack
2.1 安装依赖包
npm install html-webpack-plugin webpack webpack-cli webpack-dev-server -D
2.2 新建webpack.config.js文件
// path demo/webpack.config.js
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
/*** @type {import ("webpack").Configuration}*/
module.exports = {mode: "development",entry: path.resolve(__dirname, "./index.js"),output: {path: path.resolve(__dirname, "dist"),filename: "index.bundle.js",},experiments: { asyncWebAssembly: true },plugins: [new HtmlWebpackPlugin({template: path.resolve(__dirname, "./index.html"),}),],
};
2.3 在package.json文件中新增指令
// path demo/package.json
//...
"scripts": {"dev": "webpack server --progress --open","test": "echo \"Error: no test specified\" && exit 1"}
//...
3. 运行默认输出
3.1 wasm-pack build
wasm-pack build
3.2 修改index.js内容
// path demo/index.js
async function main() {try {const { greet } = await import("./pkg/demo.js");greet();} catch (error) {console.log(error);}
}
main();
3.3 npm run dev
npm run dev
浏览器打开http://localhost:8080/:
小结
我们已经成功地从 JavaScript 调用了 Rust,并从 Rust 调用了 JavaScript。
4. 初尝试
在 Rust 中定义一个 Transform 结构体,并通过 WebAssembly 技术,在 JavaScript 中实例化和操作这个 Transform 结构体。
4.1 修改lib.rs文件
// path demo/src/lib.rs
use wasm_bindgen::prelude::*;#[wasm_bindgen]
#[derive(Debug, Clone)]
pub struct Transform {x: f32,y: f32,width: f32,height: f32,
}#[wasm_bindgen]
impl Transform {#[wasm_bindgen(constructor)]pub fn new(x: f32, y: f32, width: f32, height: f32) -> Transform {Transform {x,y,width,height,}}#[wasm_bindgen(getter)]pub fn x(&self) -> f32 {self.x}#[wasm_bindgen(setter)]pub fn set_x(&mut self, value: f32) {self.x = value;}#[wasm_bindgen(getter)]pub fn y(&self) -> f32 {self.y}#[wasm_bindgen(setter)]pub fn set_y(&mut self, value: f32) {self.y = value;}#[wasm_bindgen(getter)]pub fn width(&self) -> f32 {self.width}#[wasm_bindgen(setter)]pub fn set_width(&mut self, value: f32) {self.width = value;}#[wasm_bindgen(getter)]pub fn height(&self) -> f32 {self.height}#[wasm_bindgen(setter)]pub fn set_height(&mut self, value: f32) {self.height = value;}
}
4.2 wasm-pack build
wasm-pack build
4.3 修改index.js文件
// path demo/index.js
async function main() {try {const { Transform } = await import("./pkg/demo.js");const transform = new Transform(0, 0, 100, 100);transform.x = 10;transform.y = 10;console.log(transform);} catch (error) {console.log(error);}
}
main();
总结
以上是对我近期探索将 Rust 编译为 WebAssembly 的总结,若有任何不准确之处,欢迎指正。