Skip to content

Commit 2b9753f

Browse files
authored
[docs] Add documentation of modularization options. (#24228)
1 parent 1e447d9 commit 2b9753f

File tree

3 files changed

+141
-11
lines changed

3 files changed

+141
-11
lines changed
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
.. _Modularized-Output:
2+
3+
==================
4+
Modularized Output
5+
==================
6+
7+
By default, emscripten outputs regular JS scripts which can be loaded on the Web
8+
via a ``script`` tag, or on the command line using Node or other JS runtime.
9+
10+
In this default configuration the generated :ref:`module` variable (and indeed
11+
all of the emscripten internal symbols) are added to the global scope. This
12+
means that only one emscripten-built program can be loaded in a given scope
13+
(since multiple modules would clobber each other's state).
14+
15+
The :ref:`modularize` setting (along with other related settings) can be used to
16+
isolate the generated module within its own private scope and/or allow multiple
17+
instances of the same module to be created.
18+
19+
This section covers the various modularization options available and how to use
20+
them.
21+
22+
23+
Using -sMODULARIZE
24+
==================
25+
26+
The :ref:`modularize` setting has two primary functions. Firstly, it
27+
puts all of the generated code inside its own scope so that the global namespace
28+
is not polluted when the JS is loaded (for example, via ``script`` tag).
29+
Secondly, it allows multiple instances of the module to be created.
30+
31+
The generated factory function is async and it returns a promise of an instance
32+
of the program. It can be called any number of times to create multiple
33+
separate and isolated instances of the same program.
34+
35+
By default, the factory function is called ``Module``, but it can be given a
36+
unique name via the ``-sEXPORT_NAME`` setting.
37+
38+
For example, a program is built using ``-sMODUARLIZE -sEXPORT_NAME=Foo`` can
39+
be instantiated using:
40+
41+
::
42+
43+
var myFoo = await Foo({ /* optional params */ });
44+
myFoo._nativeMethod();
45+
46+
47+
or:
48+
49+
::
50+
51+
Foo({ /* optional params */ }).then((myFoo) => {
52+
myFoo._nativeMethod();
53+
}
54+
55+
If node is included in the ``-sENVIRONMENT`` setting then the generated module
56+
also acts as a ``CommonJS`` module under node.
57+
58+
Because there is no global ``Module`` object in this case any parameters to the
59+
module creation are passed via the optional parameter to the factory function.
60+
For example, if you wanted to use a custom ``print`` method you could write:
61+
62+
::
63+
64+
var myFoo = await Foo({ print: myPrint });
65+
66+
67+
Generating ES6 Modules
68+
======================
69+
70+
The :ref:`EXPORT_ES6` setting can be used to instead output JavaScript in the
71+
form of an ES module. (The ES module format did not exist at time when the
72+
`MODULARIZE` setting was first created otherwise this would likely be the
73+
default).
74+
75+
Using an output filename that ends in `.mjs` will automatically enable this
76+
setting.
77+
78+
In this mode the module has a single default export which is the factory
79+
function for creating new instances of the module. For example:
80+
81+
::
82+
83+
import Foo from './emcc-output.js';
84+
var myFoo = await Foo({ print: myPrint });
85+
86+
The name ``Foo`` here can be whatever you choose and will always be assigned to
87+
the default export of the module.
88+
89+
90+
Using -sMODULARIZE=instance (experimental)
91+
==========================================
92+
93+
Emscripten has experimental support for performing only the encapsulation part of
94+
modularization, and not the ability to create multiple instances. In this
95+
mode a module is created that exports a single instance of the program rather
96+
than a factory function.
97+
98+
This setting only works when :ref:`export_es6` is enabled.
99+
100+
In this mode the default export of the module is an initializer function which
101+
allows input parameters to be passed to the instance. Other elements normally
102+
found on the module object are instead exported directly. For example:
103+
104+
::
105+
106+
// Import the default init function and a named native method
107+
import init, { _nativeMethod } from './emcc-output.js';
108+
await init({ print: myPrint });
109+
_nativeMethod();
110+
111+
Source Phase Imports (experimental)
112+
===================================
113+
114+
`Source phase imports`_ is a JavaScript proposal that adds support for importing
115+
Wasm modules via ES import statements. This allows emscripten to elide some of
116+
the auto-generated code for finding and fetching the Wasm binary.
117+
118+
See :ref:`source_phase_imports`.
119+
120+
This setting only works when :ref:`export_es6` is enabled.
121+
122+
123+
ES Module Integration (experimental)
124+
====================================
125+
126+
`Wasm ESM integration`_ is a WebAssembly proposal that allows Wasm instances to
127+
be imported directly as ES modules. This allows emscripten to elide a lot of
128+
boilerplate code for linking up Wasm and JavaScript.
129+
130+
See :ref:`wasm_esm_integration`.
131+
132+
This setting only works when :ref:`export_es6` is enabled.
133+
134+
.. _Source phase imports: https://github.com/tc39/proposal-source-phase-imports
135+
.. _Wasm ESM integration: https://github.com/WebAssembly/esm-integration

site/source/docs/compiling/index.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ This section contains topics about building projects and running the output.
99
- :ref:`Building-Projects` shows how to use :ref:`emccdoc` as a drop-in replacement for *gcc* in your existing project.
1010
- :ref:`WebAssembly` explains how Emscripten can be used to build WebAssembly files
1111
- :ref:`Running-html-files-with-emrun` explains how to use *emrun* to run generated HTML pages in a locally launched web server.
12+
- :ref:`Modularized-Output` covers the various options for generating modularized JS code.
1213
- :ref:`Deploying-Pages` covers topics related to hosting Emscripten compiled web pages on a CDN.
1314
- :ref:`GitLab` explains how to build and test projects on GitLab.
1415
- :ref:`Contrib-Ports` contains information about contrib ports.
@@ -19,6 +20,7 @@ This section contains topics about building projects and running the output.
1920

2021
Building-Projects
2122
WebAssembly
23+
Modularized-Output
2224
Dynamic-Linking
2325
Running-html-files-with-emrun
2426
Deploying-Pages

site/source/docs/getting_started/FAQ.rst

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -360,23 +360,16 @@ The crucial thing is that ``Module`` exists, and has the property
360360
``onRuntimeInitialized``, before the script containing emscripten output
361361
(``my_project.js`` in this example) is loaded.
362362

363-
Another option is to use the ``MODULARIZE`` option, using ``-sMODULARIZE``.
364-
That puts all of the generated JavaScript into a factory function, which you can
365-
call to create an instance of your module. The factory function returns a
366-
Promise that resolves with the module instance. The promise is resolved once
367-
it's safe to call the compiled code, i.e. after the compiled code has been
368-
downloaded and instantiated. For example, if you build with ``-sMODULARIZE -s
369-
'EXPORT_NAME="createMyModule"'``, then you can do this:
363+
When using the ``MODULARIZE`` is it sufficient to await the returned promise
364+
from the factory function. For example:
370365

371366
::
372367

373-
createMyModule(/* optional default settings */).then(function(Module) {
368+
createMyModule(/* optional default settings */).then((myModule) => {
374369
// this is reached when everything is ready, and you can call methods on Module
375370
});
376371

377-
Note that in ``MODULARIZE`` mode we do not look for a global Module object for
378-
default values. Default values must be passed as a parameter to the factory
379-
function. (see details in settings.js)
372+
See :ref:`Modularized-Output` for more this.
380373

381374

382375
.. _faq-NO_EXIT_RUNTIME:

0 commit comments

Comments
 (0)