Deploying on Node.js

When run from the IDE, the Debugger takes care of putting all the pieces for your WebAssembly executable into place and launch them in the Node.js runtime. For actual deployment in your larger Node.js project, some additional thought is needed.

Essentially, there are at least three files generated from with a WebAssembly project:

  • RemObjectsElements.js – this file is shared by all Elements WebAssembly modules, and contains glue code for the interaction between JavaScript and WebAssembly. While it is generated next to touer executable as part of the build, it is a static file and does not affected by the contents of your project. If yu deploy more than one WebAssembly module to the same page, you only need one copy of this file.
  • MyModule.js – this file is generated during build and contains project-specific APIs top let JavaScript code interact with the specific types and APIs your module exposes
  • MyModule.wasm – this, finally, is the actual executable containing the code you wrote, compiled to WASM.

Depending on your project type and contents, additional files might be generated or copied to the output folder, such as resources.

These are in addition to another "entry.js" JavaScript file contained in your project that defines the Node.js entry point that's mainly used for debugging purposes. For a real-life deployment, the APIs exposed by your WebAssembly module will more likely be accessed from existing JavaScript code that is already opart of your larger Node.js project.

Using a WebAssembly Module from Your Existing Node.js Project

The default template includes the entry.js file mentioned abiove, which is there to ease debugging and deployment, but that's not a requirement. The compiler-emitted MyModule.js file can be used directly with Node.js' require() function:

var MyModule = require("./MyModule").MyModule;

Where MyModule is the output name of your project. This .js file exposes APIs to access all exported member of your WebAssembly project. There is also a matching MyModule.d.ts file to allow for use from TypeScript-based projects.

The base MyModule type exposes a single called instantiate(). instantiate() accepts both an URL string or a ByteArray type to load the .wasm file. For Node.js projects, the ByteArray version should be used, for example by loading it with fs.readFileSync():

const fs = require('fs');
const path = require('path');
var MyModule = require("./MyModule").MyModule;
MyModule.instantiate(fs.readFileSync(path.resolve(__dirname, './MyModule.wasm'))).then(function(result) {
    ...
});

The Promise-typed return of instantiate() will have the resulting WebAssembly module as parameter. This will expose members for the APIs exposed by your WebAssembly module, as static methods (e.g. result.RemObjects_Elements_System_Math_Sin (for RemObjects.Elements.System.Math.Sin) and exported types (e.g. result.Program in the default template, which can be called to instantiate then and call instance members on).

const fs = require('fs');
var MyModule = require("./MyModule").MyModule;
MyModule.instantiate(fs.readFileSync(path.resolve(__dirname, './MyModule.wasm'))).then(function(result) {

    // most roundabout way to call sin:
    console.log("Sin call: " + result.RemObjects_Elements_System_Math_Sin(3)); 

    // instantiate Program
    var prog = result.Program();

    // call the HelloWorld instance method on it:
    prog.HelloWorld();
});

Note that the MyModule.js file depends on RemObjectsElements.js.

How Debugging Works

WebAssembly debugging is supported for Modules running in Node.js.

On launch, the IDE will automatically spin up a Node.js executable instance, and attach the debugger to it. This is controlled by the <DebugNodeEntryPoint> setting to the entry point .js file. The provided path name must be relative to the project output, eg. to the ./Bin folder, and will typically be pre-set by the project template.

See Also