@@ -3094,10 +3094,9 @@ def phase_final_emitting(options, state, target, wasm_target, memfile):
30943094 generated_text_files_with_native_eols = []
30953095
30963096 if settings .MODULARIZE :
3097- modularize ()
3098-
3099- if settings .USE_CLOSURE_COMPILER :
3100- module_export_name_substitution ()
3097+ final_js = post_modularize (final_js )
3098+ elif settings .USE_CLOSURE_COMPILER :
3099+ final_js = module_export_name_substitution (final_js )
31013100
31023101 # Run a final optimization pass to clean up items that were not possible to
31033102 # optimize by Closure, or unoptimalities that were left behind by processing
@@ -3109,18 +3108,6 @@ def phase_final_emitting(options, state, target, wasm_target, memfile):
31093108 # mode)
31103109 final_js = building .closure_compiler (final_js , pretty = False , advanced = False , extra_closure_args = options .closure_args )
31113110
3112- # Unmangle previously mangled `import.meta` and `await import` references in
3113- # both main code and libraries.
3114- # See also: `preprocess` in parseTools.js.
3115- if settings .EXPORT_ES6 and settings .USE_ES6_IMPORT_META :
3116- src = read_file (final_js )
3117- final_js += '.esmeta.js'
3118- write_file (final_js , src
3119- .replace ('EMSCRIPTEN$IMPORT$META' , 'import.meta' )
3120- .replace ('EMSCRIPTEN$AWAIT$IMPORT' , 'await import' ))
3121- shared .get_temp_files ().note (final_js )
3122- save_intermediate ('es6-module' )
3123-
31243111 # Apply pre and postjs files
31253112 if options .extern_pre_js or options .extern_post_js :
31263113 logger .debug ('applying extern pre/postjses' )
@@ -3566,6 +3553,11 @@ def phase_binaryen(target, options, wasm_target):
35663553 # after generating the wasm, do some final operations
35673554
35683555 if final_js :
3556+ # Note: this needs to be run before the other acorn-optimizer.js passes,
3557+ # to safely use the 'await' keyword when doing a multi-environment build.
3558+ if settings .MODULARIZE :
3559+ final_js = pre_modularize (final_js )
3560+
35693561 if settings .SUPPORT_BIG_ENDIAN :
35703562 final_js = building .little_endian_heap (final_js )
35713563
@@ -3706,10 +3698,9 @@ def node_es6_imports():
37063698'''
37073699
37083700
3709- def modularize ():
3710- global final_js
3711- logger .debug (f'Modularizing, assigning to var { settings .EXPORT_NAME } ' )
3712- src = read_file (final_js )
3701+ def pre_modularize (js_file ):
3702+ logger .debug (f'Pre-modularizing, assigning to var { settings .EXPORT_NAME } ' )
3703+ src = read_file (js_file )
37133704
37143705 # Multi-environment ES6 builds require an async function
37153706 async_emit = ''
@@ -3718,16 +3709,14 @@ def modularize():
37183709 shared .target_environment_may_be ('web' ):
37193710 async_emit = 'async '
37203711
3721- return_value = settings . EXPORT_NAME
3712+ return_value = 'Module'
37223713 if settings .WASM_ASYNC_COMPILATION :
37233714 return_value += '.ready'
37243715 if not settings .EXPORT_READY_PROMISE :
37253716 return_value = '{}'
37263717
37273718 src = '''
37283719%(maybe_async)sfunction(%(EXPORT_NAME)s) {
3729- %(EXPORT_NAME)s = %(EXPORT_NAME)s || {};
3730-
37313720%(src)s
37323721
37333722 return %(return_value)s
@@ -3755,21 +3744,53 @@ def modularize():
37553744 script_url = "typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined"
37563745 if shared .target_environment_may_be ('node' ):
37573746 script_url_node = "if (typeof __filename !== 'undefined') _scriptDir = _scriptDir || __filename;"
3758- src = '''%(node_imports)s
3747+ src = '''
37593748var %(EXPORT_NAME)s = (() => {
37603749 var _scriptDir = %(script_url)s;
37613750 %(script_url_node)s
37623751 return (%(src)s);
37633752})();
37643753''' % {
3765- 'node_imports' : node_es6_imports (),
37663754 'EXPORT_NAME' : settings .EXPORT_NAME ,
37673755 'script_url' : script_url ,
37683756 'script_url_node' : script_url_node ,
37693757 'src' : src
37703758 }
37713759
3772- final_js += '.modular.js'
3760+ final_js = js_file + '.pre-modular.js'
3761+ with open (final_js , 'w' , encoding = 'utf-8' ) as f :
3762+ f .write (src )
3763+
3764+ # Ensure Closure compiler is aware of that
3765+ # settings.EXPORT_NAME needs to be exported.
3766+ # https://stackoverflow.com/questions/46092308
3767+ if settings .USE_CLOSURE_COMPILER :
3768+ f .write ('window["%(EXPORT_NAME)s"] = %(EXPORT_NAME)s;' % {
3769+ 'EXPORT_NAME' : settings .EXPORT_NAME
3770+ })
3771+
3772+ shared .get_temp_files ().note (final_js )
3773+ save_intermediate ('pre-modularized' )
3774+ return final_js
3775+
3776+
3777+ def post_modularize (js_file ):
3778+ src = read_file (js_file )
3779+
3780+ # Replace variants of `window.Module` with `var Module`
3781+ # and remove the line containing `export{};`
3782+ # See also: `pre_modularize`
3783+ if settings .USE_CLOSURE_COMPILER :
3784+ src = src .replace ('window.%s' % settings .EXPORT_NAME ,
3785+ 'var %s' % settings .EXPORT_NAME )
3786+ src = src .replace ('window["%s"]' % settings .EXPORT_NAME ,
3787+ 'var %s' % settings .EXPORT_NAME )
3788+ src = src .replace ('export{};\n ' , '' )
3789+
3790+ # Prepend static import declarations, if any
3791+ src = node_es6_imports () + src
3792+
3793+ final_js = js_file + '.post-modular.js'
37733794 with open (final_js , 'w' , encoding = 'utf-8' ) as f :
37743795 f .write (src )
37753796
@@ -3788,14 +3809,14 @@ def modularize():
37883809''' % {'EXPORT_NAME' : settings .EXPORT_NAME })
37893810
37903811 shared .get_temp_files ().note (final_js )
3791- save_intermediate ('modularized' )
3812+ save_intermediate ('post-modularized' )
3813+ return final_js
37923814
37933815
3794- def module_export_name_substitution ():
3795- global final_js
3816+ def module_export_name_substitution (js_file ):
37963817 logger .debug (f'Private module export name substitution with { settings .EXPORT_NAME } ' )
3797- src = read_file (final_js )
3798- final_js += '.module_export_name_substitution.js'
3818+ src = read_file (js_file )
3819+ final_js = js_file + '.module_export_name_substitution.js'
37993820 if settings .MINIMAL_RUNTIME and not settings .ENVIRONMENT_MAY_BE_NODE and not settings .ENVIRONMENT_MAY_BE_SHELL :
38003821 # On the web, with MINIMAL_RUNTIME, the Module object is always provided
38013822 # via the shell html in order to provide the .asm.js/.wasm content.
@@ -3804,8 +3825,10 @@ def module_export_name_substitution():
38043825 replacement = "typeof %(EXPORT_NAME)s !== 'undefined' ? %(EXPORT_NAME)s : {}" % {"EXPORT_NAME" : settings .EXPORT_NAME }
38053826 src = re .sub (r'{\s*[\'"]?__EMSCRIPTEN_PRIVATE_MODULE_EXPORT_NAME_SUBSTITUTION__[\'"]?:\s*1\s*}' , replacement , src )
38063827 write_file (final_js , src )
3828+
38073829 shared .get_temp_files ().note (final_js )
38083830 save_intermediate ('module_export_name_substitution' )
3831+ return final_js
38093832
38103833
38113834def generate_traditional_runtime_html (target , options , js_target , target_basename ,
0 commit comments