Rust + WASM using bindgen
This is an advance topic using bindgen
, as second step to my previouse post
- Create project folder
utils2
- cd to this folder
- from this folder create your lib:
// install rust if not yet done
// curl sh.rustup.rs -sSf | sh
mkdir utils2
cd utils 2
cargo init --lib
// Or it can be created in one line as:
cargo new utils2 --lib
cd utils2
- make the default toolchain as
nightly
aswasm
is only supported in nightly now:
rustup override set nightly
// Add was32 target if not yet installed
rustup target add wasm32-unknown-unknown --toolchain nightly
note:
Platforms are defined by their Target Triplet
that is: machine-vendor-operatingsystem
:
- Machine / the name of the CPU family/model: wasm32,
- The vendor: no specific, so it is unknown,
The operating system name: no specific, so it is unknown.
Create
npm
package file by running:
npm init
the above will create package.json
.
- Install
webpack
npm requirements, thenode_modules
folder will be created:
// brew install node
npm install -D webpack webpack-cli webpack-dev-server
the above will alter the package.json
and make it loos something like:
{
"name": "utils2",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"devDependencies": {
"webpack": "^4.27.1",
"webpack-cli": "^3.1.2",
"webpack-dev-server": "^3.1.10"
}
}
- Create
domUtils.js
,index.html
,index.js
andwebpack.config.js
files, so that the structure be as below:
// if you need to install tree, it can be done by
// brew install tree
$ tree .
.
├── Cargo.lock
├── Cargo.toml
├── domUtils.js
├── index.html
├── index.js
├── package.json
├── src
│ └── lib.rs
└── webpack.config.js
- Open the folder files in your idea, and update them, as shown in point #11
$ idea .
- Build the rust wasm lib using
wasm-pack
as:
// cargo install wasm-pack
wasm-pack build
// this will create the standard target folder, and additional folder called pkg
// the pkg folder tree is:
├── pkg
│ ├── utils2.d.ts
│ ├── utils2.js
│ ├── utils2_bg.d.ts
│ └── utils2_bg.wasm
- Run the server as:
npx webpack-dev-server
- The files:
Cargo.toml:
[package]
name = "utils2"
version = "0.1.0"
authors = ["Hasan Yousef"]
edition = "2018"
[dependencies]
wasm-bindgen = "0.2.29"
[lib]
crate-type = ["cdylib"]
domUtils.js:
export const appendStringToBody = (value) => {
const text = document.createTextNode(value);
document.body.appendChild(text);
}
use wasm_bindgen::prelude::*;
// Define the JS function signature
#[wasm_bindgen(module = "../domUtils")]
extern {
fn appendStringToBody(s: &str);
}
#[wasm_bindgen]
pub fn run(my_text :&str) {
// Call the JavaScript function
#[allow(unused_unsafe)]
unsafe {
appendStringToBody(my_text);
}
}
webpack.config.js:
const path = require("path");
module.exports = {
entry: "./index.js",
output: {
path: path.resolve(__dirname, "dist"),
filename: "index.js",
},
mode: "development"
};
index.js:
import("./pkg/my_app").then(wasmModule => {
wasmModule.run("hi there");
});
index.html:
<!DOCTYPE html>
<html>
<head>
<script src="./index.js"></script>
<head>
<body></body>
<html>