Skip to content

MODULARIZE & EXPORT_NAME build options odditiesย #7950

Closed

Description

@juj

Consider

$ emcc tests\hello_world.c -s MODULARIZE=1 -o a.html

This produces a web page that does not run, but gives no build errors either.

There are two things that are odd about the generated build.

First, I think the history of -s MODULARIZE=1 was intended to be primarily used when building to JavaScript with -o a.js, so the intent is that one would manually invoke the generate Module() function (defined with -s EXPORT_NAME= option) to start the app. But when one is targeting HTML with any of the default html shell files that Emscripten provides (no --shell-file directive passed, or --shell-file src/shell_minimal.html) it seems that we should be automatically be generating a Module(); invocation there to start the page.

Second, why is the default value of the -s EXPORT_NAME= option called Module? That seems wrong. Module is supposed to be an object that contains import/export interactions with the generated page. In MODULARIZE mode EXPORT_NAME specifies the name of the function that one should call to launch the page. Calling this function also Module seems like we are calling two different things by the same name, and by default, one would need to call Module(Module); to run the page. Hence when building

$ emcc tests\hello_world.c -s MODULARIZE=1 -o a.html

it is not possible to launch the generated build even from web console.

Perhaps default value of EXPORT_NAME should be changed to something like 'EmscriptenCode', so that the default launch sequence would look like EmscriptenCode(Module);, and our default shells would add a {{{ EXPORT_NAME }}}(Module); directive to them?

Activity

  1. juj commented on Jan 29, 2019

    @juj
    CollaboratorAuthor

    Hmm, further, docs in settings.js say

    // page, it will use the global scope. With MODULARIZE set, we will instead emit
    //
    //   var EXPORT_NAME = function(Module) {
    //     Module = Module || {};
    //     // .. all the emitted code from emscripten ..
    //     return Module;
    //   };
    //
    // where EXPORT_NAME is from the option of the same name
    

    However if I do a -s MODULARIZE=1 -s EXPORT_NAME='EmscriptenCode' build, then I don't get

    var EmscriptenCode = function(Module) {
      Module = Module || {};
      // .. all the emitted code from emscripten ..
      return Module;
    };

    in my build. But instead I get

    var EmscriptenCode = (function() {
      return (function(EmscriptenCode) {
        EmscriptenCode = EmscriptenCode || {};
        ...
        return EmscriptenCode;
      });
    })();

    which seems unnecessary - the inner Module should not need to change to EmscriptenCode?

  2. kripken commented on Jan 29, 2019

    @kripken
    Member

    MODULARIZE by itself does not run the code, yes - intentionally, so you can instantiate it multiple times later as needed.

    MODULARIZE_INSTANCE will create an instance for you, and call it (so you can't create more than one).

    About the name being replaced in more places - yeah, that might be redundant, maybe we did it for aesthetic purposes. I'm not sure - may need to look through the PRs.

  3. stale commented on Jan 29, 2020

    @stale

    This issue has been automatically marked as stale because there has been no activity in the past year. It will be closed automatically if no further activity occurs in the next 7 days. Feel free to re-open at any time if this issue is still relevant.

  4. yowl commented on May 17, 2020

    @yowl

    See this is closed, but still a little confused, not being a JS expert. If I build with -s MODULARIZE=1 -s EXPORT_NAME='"createModule"' -s MODULARIZE_INSTANCE=1 --shell-file "shell_minimal.html" in the HTML there is an object created called Module :

          var Module = {
            preRun: [],
            postRun: [],
    ...
    

    but I dont think it gets used at

    ...
      return createModule
    }
    )(typeof createModule === 'object' ? createModule : {});
    if (typeof exports === 'object' && typeof module === 'object')
          module.exports = createModule;
        else if (typeof define === 'function' && define['amd'])
    ...
    

    Would I be right in saying that

    1. the Module created in shell_minimal.html is not used
    2. To use Module created in shell_minimal.html I should drop -s MODULARIZE_INSTANCE=1 and pass it in to createModule e.g.
    createModule(Module);
    

    Which I could put in shell_minimal.html ?

  5. kripken commented on May 18, 2020

    @kripken
    Member

    @yowl note that MODULARIZE_INSTANCE was recently removed. it did lead to complicated situations like this one. You can do similar things by manually creating an instance, which avoids the possible confusion between the generator function (createModule in your example) and the parameters to that function, which are Module in that shell file.

    In general I think the default html shell files just set values to Module, so they are not aware of MODULARIZE or EXPORT_NAME - you may need a custom html in some cases.

  6. added 3 commits that reference this issue on Jan 27, 2026
    cd26eea
    4eebe4c
    ca1e45c
  7. added a commit that references this issue on Feb 13, 2026
    94ed0ff
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions