By default, Emscripten creates a module which can be used from both Node.JS and the browser, but it has the following issues:
- The module pollutes the global namespace
- The module is created with the name
Module
(in my case, I requirestreamingPercentiles
) - The module cannot be loaded by some module loaders such as require.js
While the above issues can (mostly) be corrected by using –s MODULARIZE=1
, it changes the semantics of the resulting JavaScript file, as the module now returns a function rather than an object. For example, code which previously read var x = new Module.Klass()
would become var x = new Module().Klass()
. I found this semantic change unacceptable, so I decided to abandon Emscripten’s -s MODULARIZE=1
option in favor of hand-crafting a UMD module.
I determined that the most appropriate pattern for my use case was the no dependencies pattern from UMD’s templates/returnExports.js
. Applied to an Emscripten module, and using the default module name streamingPercentiles
, the stanzas look like the following:
umdprefix.js
:
|
|
umdsuffix.js
:
|
|
While I might be able to use Emscripten’s --pre-js
and --post-js
“s options to prepend and append the above JavaScript files, these options do not guarantee in all cases that the above JavaScript files will be first and last. Therefore, I decided to prepend and append the JavaScript manually.
As my build system is CMake based, I needed to change change the compilation process to generate an intermediate file streamingPercentiles-unwrapped.v1.js
, and then use some CMake magic to prepend and append the above JavaScript files:
|
|
With the above code, all of the original three issues are fixed without any semantic changes for users.