Vue + WebAssembly

Brock Reece
3 min readDec 29, 2017

I have recently been experimenting with using Web Assembly in my Vue project and have enjoyed programming in Rust but found that whilst the tooling around compiling the WebAssembly module is nice and easy, using it in your web application requires a bit of fiddling.

The following article hopes to outline the way I integrated my Web Assembly functions into every component in my Vue-cli generated Webpack project.

Webpack integration

My main gripe with current implementation of Web Assembly is the rather cumbersome way of loading your Web Assembly module into your application.

fetch('simple.wasm').then(response =>
response.arrayBuffer()
).then(bytes =>
WebAssembly.instantiate(bytes, importObject)
).then(results => {
results.instance.exports.exported_func();
});

After a quick Google search, I found a great Webpack loader that allows you to easily import your .wasm file into your project. To use this loader, you will need to add the following to your Webpack config.

// build/webpack.base.conf.js
module: {
rules: [
...
{
test: /\.wasm$/,
loaders: ['wasm-loader']
}
]
}

After you have set up your loader, you can import your .wasm file as you would any other JS module. The default export from the loader is a function returning a native Promise, the promise resolves to a WebAssembly.Instance.

import artihmeticModule from './assets/wasm/artihmetic.wasm';const arithmetic = artihmeticModule().then(({ instance }) => {
return instance.exports
});

Using WA with Vue

I believe that in a real world Application you will probably need to load multiple wasm modules, so it would make sense to create a simple reusable method to extract the functions from the WebAssembly Instance.

import artihmeticModule from './assets/wasm/artihmetic.wasm';
import fibinachiModule from './assets/wasm/fibinachi.wasm';
const extractModule = async (module) => {
const { instance } = await module();
return instance.exports;
};
const arithmetic = extractModule(artihmeticModule);
const fibinachi = extractModule(fibinachiModule);

To make the Web Assembly functions available in all of your Vue components, you can add something like this to the Vue prototype.

Vue.prototype.$wasm = {
arithmetic: extractModule(artihmeticModule),
fibinachi: extractModule(fibinachiModule),
};

You can now call any imported Web Assembly function in your Vue component using the following syntax…

this.$wasm.arithmetic.add(1, 2) // 3

Plugin

I have built a Vue plugin to wrap the above process, which makes registering WebAssembly modules as easy as…

// main.js
import Vue from 'vue'
import VueWasm from 'vue-wasm';
import arithmeticModule from './assets/wasm/arithmetic.wasm';

VueWasm(Vue, { modules: { arithmetic: arithmeticModule } });

After registering the plugin you will again be able to access the WebAssembly functions from any component using the same syntax as before.

this.$wasm.arithmetic.add(1, 2) // 3

Summary

I see the immense potential of Web Assembly and I can also see a (not so distant) future where Web developers wouldn’t necessarily build their own Rust based modules, but would consume third party Web Assembly utility libraries similar to how we use JS based libraries today, like Lodash.

To facilitate this, we will need to make it as easy as possible for developers to integrate it into their current workflow and technologies by reducing the barrier to entry. I hope the above article and plugin will help Vue developers get started with Web assembly today.

--

--