Rust编译到WebAssembly例子

full rust webassembly

随着WebAssembly越来约完善,很多Web应用可以利用它解决性能计算的业务场景,甚至WebAssembly未来还有计划实现调用外部JavaScript方法的计划。

目前官方推荐使用四种语言编写WebAssembly的源码,它们分别是

  • C/C++ 所有人都知道的语言
  • Rust 我最喜欢的语言
  • AssemblyScript 如果你写C/C++,Rust不舒服,这是最佳的选择
  • WebAssembly 直接编写WebAssembly的格式,难度比较大

无论选用什么语言,套路都是把源码编译到WebAssembly类型的字节码,文件扩展名是.wasm的文件,然后浏览器加载WebAssembly文件,调用源码的方法。

Rust默认是不支持WebAssembly类型编译的,需要安装一个包

cargo install wasm-pack

为了测试,我们安装上前段开发必备软件包nodejs,然后我们初始化一个Rust Lib类型的项目

$ cargo new --lib hello_wasm
    Created library `hello_wasm` project

使用编辑器,比如VSCode打开项目,打开Cargo.toml文件,添加一个依赖

Cargo.toml

[package]
name = "hello_wasm"
version = "0.1.0"
authors = ["Nicholas Lee <lizhongit@gmail.com>"]
edition = "2018"

# 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"

打开src/lib.rs文件,编写如下内容,旧内容直接全删除掉就好

src/lib.rs

use wasm_bindgen::prelude::*;

#[wasm_bindgen]
pub fn sum(a: u32, b: u32) -> u32 {
  a + b
}

编写结束之后,到了最关键的步骤:编译

wasm-pack build

待编译程序跑完之后,如果控制台没出错的话,应该多出了一个pkg目录,进去看一下有这些东西

$ ll pkg
total 56
-rw-r--r--  1 Nicholas  staff   160B Nov 12 16:19 hello_wasm.d.ts
-rw-r--r--  1 Nicholas  staff    81B Nov 12 16:19 hello_wasm.js
-rw-r--r--  1 Nicholas  staff   197B Nov 12 16:19 hello_wasm_bg.js
-rw-r--r--  1 Nicholas  staff   180B Nov 12 16:19 hello_wasm_bg.wasm
-rw-r--r--  1 Nicholas  staff   134B Nov 12 16:19 hello_wasm_bg.wasm.d.ts
drwxr-xr-x  3 Nicholas  staff    96B Nov 12 16:20 node_modules
-rw-r--r--  1 Nicholas  staff    73B Nov 12 15:47 package-lock.json
-rw-r--r--  1 Nicholas  staff   285B Nov 12 16:19 package.json

pkg/package.json

{
  "name": "hello_wasm",
  "collaborators": [
    "Nicholas Lee <lizhongit@gmail.com>"
  ],
  "version": "0.1.0",
  "files": [
    "hello_wasm_bg.wasm",
    "hello_wasm.js",
    "hello_wasm.d.ts"
  ],
  "module": "hello_wasm.js",
  "types": "hello_wasm.d.ts",
  "sideEffects": false
}

为了测试,我们需要链接一下

cd pkg
npm link
cd ..

接下来,需要测试是否可以用了,你可以创建一个新的NPM项目测试,我比较懒,直接在当前项目下干这事了,创建以下文件

package.json

{
  "scripts": {
    "serve": "webpack-dev-server"
  },
  "dependencies": {
    "hello_wasm": "^0.1.0"
  },
  "devDependencies": {
    "webpack": "^4.25.1",
    "webpack-cli": "^3.1.2",
    "webpack-dev-server": "^3.1.10"
  }
}

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>hello-wasm Rust WebAssembly 例子 - 琼台博客</title>
  </head>
  <body>
    <script src="./app.js"></script>
  </body>
</html>

app.js

const wasm = import("./node_modules/hello_wasm/hello_wasm.js");
wasm.then(module => {
  console.log(module.sum(61, 90));
})

webpack.config.js

const path = require('path');
module.exports = {
  entry: "./app.js",
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "app.js",
  },
  mode: "development"
};

链接一下我们的hello_wasm这个Rust编译出来的本地包

npm link hello_wasm

安装NPM依赖

npm install 

运行测试

npm run serve

打开浏览器,地址栏输入http://localhost:8080/回车,打开控制台,不出意外的话控制台会输出151数字,大功告成~

分享

TITLE: Rust编译到WebAssembly例子

LINK: https://www.qttc.net/539-rust-webassembly-example.html

NOTE: 原创内容,转载请注明出自琼台博客