Modules
Create JavaScript modules or CommonJS with -cheerp-make-module
JavaScript modules
Use the -cheerp-make-module=es6
flag to generate a JavaScript module:
Using modules
In HTML
In another JavaScript module
There are a couple of important things to notice:
- Cheerp modules provide an initialization function as default export, in the import directive you can name it whatever you want
- This function once called will return a Promise that will resolve when the module has been instantiated, and will return an object with the JSExported function and classes as properties
- The instantiation function has to be called only once. Any additional call is Undefined Behaviour (in the current implementation it would perform initialization of C++ state twice, so the logic integrity of the program will be compromised, but do not rely on any specific behaviour since it might change in future versions).
Why use JavaScript modules?
In regular JavaScript a script has no knowledge of its own location, so all information about location of a file are relative to the root of the server.
This means that for regular Cheerp compilation you will have to know where a file is located in advance (and provide this information at compile time via -cheerp-secondary-output-file=...
and -cheerp-secondary-output-path=...
).
Modules offer a more manageable solution: the default will be having the WebAssembly file in the same folder of the JavaScript one, compilation arguments will overwrite this, and advanced options allows even to provide at runtime the location or content of the WebAssembly file.
What should I know about JavaScript modules?
- modules code is executed in a separate realm/scope, meaning that the global namespace will not be polluted
- export directives allow module to expose JavaScript function, object or classes as an interface
- import directives allow external code to access the expored functions
- modules can be imported only by other modules
- modules initialization code is only ever executed once (even if imported multiple times) For plenty of background and technical information around ES6 modules we reccomend MDN’s guide of V8’s guide on JavaScript modules.
The initialisation function
- Module instantiating function has to be called exactly once
- The module instantiating function takes either no arguments (so default are used) or an object with options to be passed to the instantiating logic. Currently supported parameters are:
absPath
- the absolute Path of the secondary file (in the common case, the Wasm file) from the root of the pagebuffer
- a buffer containing the content of the secondary file (in the common case, the Wasm file)
- The module instantiating function returns a Promise that will resolve to an object (possibly empty) wrapping the
[[cheerp::jsexport]]
-ed functions or classes. - Both static or dynamic imports are supported
These instantiation are all somehow equivalent:
- instantiation with no arguments
- instantiation with no absolute path
- instantiation with buffer
- instantiation with path relative to current module
- dynamic instantiation with no arguments
ES6 modules and top-level await
CommonJS
Cheerp supports the CommonJS standard for JavaScript modules via the -cheerp-make-module=commonjs
option.
With this option an exports
object will be automatically populated with all the exported functions.
This allows JavaScript code from other files to use require()
and import them.
The actual object returned by require()
is a Promise
, since the code produced by Cheerp may contain WebAssembly (which is only loaded and compiled asynchronously).
For example, suppose that you have a project in which you need to sort a big array, and you want to replace the slow Array.sort()
with a faster version. Instead of writing your own sorting function, you can use std::sort()
from the C++ STL:
You can compile the above code with /opt/cheerp/bin/clang++ -target cheerp sort.cpp -o sort.js -cheerp-make-module=commonjs
and put the resulting sort.js
in your project source folder.
Than, using it is as easy as:
This option is useful to those who wish to use code compiled with Cheerp from Node.js, but it also allows Cheerp code to be used with JavaScript bundlers such as Webpack.