Using rust modules in JavaScript/Web Development (Part 2 / 3) [Webpack]

Please read the Part 1 of the series here :

Part 1 of the post was primarily concerned with integrating rust modules with JavaScript with the help of wasm. But that involved a lot of manual procedures.

Manual procedures:

  1. Do a build of rust modules to generate wasm output.
  2. Move the generated web.wasm file to the assets directory.

One way of solving this is by writing a custom shell script which does this whenever the rust file changes.

Another more streamlined way is using webpack. 🧞‍♂️🎉

*Prerequisite:

Setup the rust project from Part 1 of this post. Follow the Setting up the rust project and Building wasm from rust part of the post.

Using rust modules on front-end using Webpack

Setting up a webpack based frontend project

Lets start by creating a new project

  1. mkdir webpackasm && cd webpackasm — creating the project directory
  2. git init && yarn init or git init && npm init — initialising git and npm/yarn
  3. yarn add --dev webpack webpack-cli webpack-dev-server — installing dependencies.

Now create the following directory/file structure

webpackasm
├── index.html
├── package.json
├── src
│ └── index.js
├── webpack.config.js
└── yarn.lock

Change the contents of webpackasm/index.html to

<html>
<head>
<title>Webpack WASM</title>
</head>
<body>
Hello
<script type="text/javascript" src="bundle.js"></script>
</body>
</html>

Your webpack.config.js should look like:

const path = require('path');
module.exports = {
entry: './src/index.js',
mode: process.env.NODE_ENV || 'development',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
}
};

You package.json should look like:

{
"name": "webpackasm",
"version": "1.0.0",
"main": "index.js",
"author": "Atul R <atulanand94@gmail.com>",
"license": "MIT",
"scripts": {
"start": "webpack-dev-server --open",
"build": "webpack -p && cp index.html dist/index.html",
"clean": "rm -rf ./dist/*"
},
"devDependencies": {
"webpack": "^4.4.1",
"webpack-cli": "^2.0.13",
"webpack-dev-server": "^3.1.1"
}
}

And finally webpackasm/src/index.js should look like this:

console.log('I am alive!!!');

Lets try and run this:

yarn start or npm start

Should open up a browser window that would look like this.

Basic webpack setup with live reload

Perfect! now we have a working webpack setup with livereload.

Now lets add the secret ingredients to make rust modules work with webpack.

  1. yarn add --dev wasm-loader rust-native-wasm-loader — add the necessary loaders
  2. Modify the webpack.config.js to
const path = require('path');
module.exports = {
entry: './src/index.js',
mode: process.env.NODE_ENV || 'development',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [{
test: /\.rs$/,
use: [{
loader: 'wasm-loader'
},
{
loader: 'rust-native-wasm-loader',
options: {
release: true
}
}]
}]
}
};

Also now add the following code to src/index.js

import loadWasm from 'path/to/the/lib.rs';
console.log('I am alive!!!');
loadWasm().then(result => {
const {add, subtract, multiply} = result.instance.exports;
console.log('4 + 2 = ', add(4, 2));
console.log('4 - 2 = ', subtract(4, 2));
console.log('4 * 2 = ', multiply(4, 2));
});

Let break down the above code.

import loadWasm from 'path/to/the/lib.rs';

This is the same lib.rs file from the web crate that we created. Webpack would detect that this is a rust file and run the loaders specified in the webpack config. In this case it would be rust-native-wasm-loader and wasm-loader. These loaders would compile lib.rs into wasm and then initialised the wasm in the javascript environment.

All the manual stuff that we did in the Part 1 is now automated by webpack.

Lets run it !

yarn start should open up

Loading rust modules using webpack

How cool is that !! 🎉

Loading rust modules in the backend

You can use the same technique rust -> wasm to load rust modules in the node backend. But there is an alternate technique that makes working with rust modules much easier on the node side. Also, in most cases wasm for nodejs is just overkill.

Part 3 would cover how to load up rust modules in the backend (NodeJS) without Webassembly.

Link to Part 3: https://medium.com/@atulanand94/using-rust-modules-for-javascript-web-development-part-3-3-nodejs-7c71e4ae23fe

Source Code:

https://github.com/master-atul/rust-module-in-javascript-blog-series

References:

Like what you read? Give Atul a round of applause.

From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.