Hello World
Note: The final code for this example can be found on GitHub.
In this introductory example, we will develop a NodeJS-based application that calls a WebAssembly module that in turn, calls a native "OS" function. This is exactly the same call chain as was used in the client-side example:
JavaScript
--> WebAssembly
--> Native "OS" function
In this case, we will invoke the a simple WASI module that does nothing more than writing hello world
to standard out.
However, as we saw with the client-side hello-world
example, file descriptors such as "standard in" and "standard out" are not normally available to a WebAssembly module since they belong to the underlying "OS". Therefore, we must again make use of the following package:
Package Name
Description
@wasmer/wasi
A set of JavaScript polyfills that bridge the gap between the black-box world of a WebAssembly module and functionality available from the host environment
Setup Instructions
Step-By-Step Guide
Change into some development directory
$ cd <some_development_directory>
Create and then change into a new project directory, then run
npm init
$ mkdir wasmer-js-node-hello-world $ cd wasmer-js-node-hello-world $ npm init
After answering all the questions from
npm init
, you will have a configuredpackage.json
file.Declare the use of package
@wasmer/wasi
as a runtime dependency by running the command:$ npm install --save @wasmer/wasi
Download the WebAssembly module
helloworld.wasm
and store it in this directoryCreate the file
index.js
and add the coding shown below.Important DifferenceIn contrast to running in the browser, the server-side implementation of the same Wasm module is noticeably smaller.
When running server-side, we do not need to write any code to obtain the contents of standard out after the Wasm module has executed, since when running server-side, anything written to standard out by a Wasm module appears directly in the console.
const fs = require("fs") const { WASI } = require("@wasmer/wasi") const nodeBindings = require("@wasmer/wasi/lib/bindings/node") const wasmFilePath = "./helloworld.wasm" // Instantiate a new WASI Instance let wasi = new WASI({ args: [wasmFilePath], env: {}, bindings: { ...(nodeBindings.default || nodeBindings), fs: fs } }) // Async function to run our Wasm module/instance const startWasiTask = async pathToWasmFile => { // Fetch our Wasm File let wasmBytes = new Uint8Array(fs.readFileSync(pathToWasmFile)).buffer // Instantiate the WebAssembly file let wasmModule = await WebAssembly.compile(wasmBytes); let instance = await WebAssembly.instantiate(wasmModule, { ...wasi.getImports(wasmModule) }); // Start the WASI instance wasi.start(instance) } // Everything starts here startWasiTask(wasmFilePath)
Save
index.js
and run it using:$ node index.js Hello World!
Next, let's take a look at running Wasm modules whose interfaces require transformation.
Last updated
Was this helpful?