You can notice the above image has mention of crates, rust macros (unused_imports) and that is all compiled via Webpack.
You can skip my introduction, if you are just interested in RUST + WebAssembly boilerplate code here
Intro
I recently got hooked to RUST programming language.
Rust initially looks very difficult, and yes it is.
But it was also a bit welcoming to me since Rust does not have
classes. (WIN WIN for me I don't like CLASS) The same reason why I liked GO very much and built a 2D RPG Game in GoLang
But since the day I started reading RUST, I stopped using GO. (In no way GO is bad, its just Rust has something magical)
Rust definitely made me understand what is a Garbage Collector (that's what I like to think so o_0), cause Rust gives its memory safety guarantees without needing a garbage collector. I really love Rust how to helped me understand Stack & Heap (I had NO computer science background, I'm just a Frontend developer... JavaScript world).
WebAssembly has become quite mature in the past couple of years. It’s certainly no longer a bleeding-edge technology. Build tools became quite sophisticated, so you can build everything with one npm command.
Folder structure :
├── src
| └── lib.rs
├── public
| └── index.js
| └── index.html
├── package.json
├── webpack.config.js
└── cargo.toml
└── web.config
Let's begin * _
Cargo.toml needs to define crate type as dynamic C library hence we define it like below
[lib]
crate-type = ["cdylib"]
And some special dependencies.
Please update dependencies.web-sys
as you add more feature from JavaScript world.
[dependencies]
console_error_panic_hook = "=0.1.6"
js-sys = "0.3.39"
lazy_static = "1.4.0"
nalgebra = "0.21.0"
wasm-bindgen = "0.2.62"
[dependencies.web-sys]
version = "0.3.39"
features = [
'Document',
'Element',
'EventTarget',
'MouseEvent',
'Window',
]
Next it is web.config file
This file includes Rust .wasm file into our application
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<staticContent>
<mimeMap fileExtension=".wasm" mimeType="application/wasm" />
</staticContent>
</system.webServer>
</configuration>
webpack.config
This is where all magic happens. Webpack compiles our Rust code into JavaScript during development and into Web-Assembly if you run npm run build
const webpack = require('webpack');
const WasmPackPlugin = require('@wasm-tool/wasm-pack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
module.exports = (env, args) => {
const isProduction = (args.mode === 'production');//package.json scripts -> build
return {
entry: './public/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: isProduction ? '[name].[contenthash].js' : '[name].[hash].js'
},
plugins: [
new HtmlWebpackPlugin({
template: './public/index.html'
}),
new WasmPackPlugin({
crateDirectory: path.resolve(__dirname, ".")// (where the cargo.toml file is located)
}),
new webpack.ProvidePlugin({
TextDecoder: ['text-encoding', 'TextDecoder'],
TextEncoder: ['text-encoding', 'TextEncoder'],
}),
],
}
};
And of course make srue you have a ./public
folder with a index.html and index.JS
file.
index.js
This is the main front-end file, it reads our Rust code. Please make sure you don't use ES6 imports here, use commonjs alike import to avoid compile errors. This line ../pkg/index.js
webpack will create pkg
folder, don't worry. Here say_hello_from_rust
is actually coming from src/lib.rs
file.
const rust = import('../pkg/index.js');
rust.then(r => {
r.say_hello_from_rust();
})
.catch(console.error);
src/lib.rs
And now inside RUST ./src/lib.rs
file :
wasm_bindgen
created by Rust team, a library that facilitate high-level interactions between wasm modules and JavaScript.
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(js_namespace = console)]
fn log(s: &str);
}
#[wasm_bindgen]
pub fn say_hello_from_rust() {
log("Hello from Rust World!");
}
package.json
npm i @wasm-tool/wasm-pack-plugin html-webpack-plugin text-encoding webpack webpack-cli webpack-dev-server --save-dev
There are few more scripts which helps us compile the code inside package.json
But you need to add this line to your project before every build
rustup run nightly cargo build --target wasm32-unknown-unknown
So I created these helper script calls, which can be found inside package.json
npm run build
which will give you production ready code to be deployed without worrying to add the above scary line every-time.
Result
After a couple of days experimenting with Rust+Wasm, it seems to be a good combo. Great performance and feature support opens a land of opportunities. Build tools are also great and Wasm should now be supported by all major browsers.
Source code: https://github.com/steelx/rust-wasm-boilerplate
Hope you have fun working with RUST and WASM. I'm definitely going to stick with RUST :)
Top comments (0)