2121
2222Usage:
2323
24- file_packager TARGET [--preload A [B..]] [--embed C [D..]] [--exclude E [F..]] [--js-output=OUTPUT.js] [--no-force] [--use-preload-cache] [--indexedDB-name=EM_PRELOAD_CACHE] [--separate-metadata] [--lz4] [--use-preload-plugins] [--no-node] [--help]
24+ file_packager TARGET [--preload A [B..]] [--embed C [D..]] [--exclude E [F..]] [--js-output=OUTPUT.js] [--no-force] [--use-preload-cache] [--indexedDB-name=EM_PRELOAD_CACHE] [--separate-metadata] [--lz4] [--use-preload-plugins] [--no-node] [--export-es6] [-- help]
2525
2626 --preload ,
2727 --embed See emcc --help for more details on those options.
4141
4242 --export-name=EXPORT_NAME Use custom export name (default is `Module`)
4343
44+ --export-es6 Wrap generated code inside ES6 exported function
45+
4446 --no-force Don't create output if no valid input file is specified.
4547
4648 --use-preload-cache Stores package in IndexedDB so that subsequent loads don't need to do XHR. Checks package version.
@@ -129,6 +131,7 @@ def __init__(self):
129131 self .use_preload_plugins = False
130132 self .support_node = True
131133 self .wasm64 = False
134+ self .export_es6 = False
132135
133136
134137class DataFile :
@@ -362,7 +365,7 @@ def main(): # noqa: C901, PLR0912, PLR0915
362365 To revalidate these numbers, run `ruff check --select=C901,PLR091`.
363366 """
364367 if len (sys .argv ) == 1 :
365- err ('''Usage: file_packager TARGET [--preload A [B..]] [--embed C [D..]] [--exclude E [F..]] [--js-output=OUTPUT.js] [--no-force] [--use-preload-cache] [--indexedDB-name=EM_PRELOAD_CACHE] [--separate-metadata] [--lz4] [--use-preload-plugins] [--no-node] [--help]
368+ err ('''Usage: file_packager TARGET [--preload A [B..]] [--embed C [D..]] [--exclude E [F..]] [--js-output=OUTPUT.js] [--no-force] [--use-preload-cache] [--indexedDB-name=EM_PRELOAD_CACHE] [--separate-metadata] [--lz4] [--use-preload-plugins] [--no-node] [--export-es6] [-- help]
366369 Try 'file_packager --help' for more details.''' )
367370 return 1
368371
@@ -391,6 +394,9 @@ def main(): # noqa: C901, PLR0912, PLR0915
391394 elif arg == '--no-force' :
392395 options .force = False
393396 leading = ''
397+ elif arg == '--export-es6' :
398+ options .export_es6 = True
399+ leading = ''
394400 elif arg == '--use-preload-cache' :
395401 options .use_preload_cache = True
396402 leading = ''
@@ -485,6 +491,11 @@ def main(): # noqa: C901, PLR0912, PLR0915
485491 diagnostics .error ('TARGET should not be the same value of --js-output' )
486492 return 1
487493
494+ if options .from_emcc and options .export_es6 :
495+ diagnostics .error ('Can\' t use --export-es6 option together with --from-emcc since the code should be embedded '
496+ 'within emcc\' s code' )
497+ return 1
498+
488499 walked .append (__file__ )
489500 for file_ in data_files :
490501 if not should_ignore (file_ .srcpath ):
@@ -621,20 +632,38 @@ def generate_js(data_target, data_files, metadata):
621632 if options .from_emcc :
622633 ret = ''
623634 else :
624- ret = '''
635+ if options .export_es6 :
636+ ret = 'export default async function loadDataFile(Module) {\n '
637+ else :
638+ ret = '''
625639 var Module = typeof %(EXPORT_NAME)s != 'undefined' ? %(EXPORT_NAME)s : {};\n ''' % {"EXPORT_NAME" : options .export_name }
626640
627641 ret += '''
628642 Module['expectedDataFileDownloads'] ??= 0;
629- Module['expectedDataFileDownloads']++;
630- (() => {
643+ Module['expectedDataFileDownloads']++;'''
644+
645+ if not options .export_es6 :
646+ ret += '''
647+ (() => {'''
648+
649+ ret += '''
631650 // Do not attempt to redownload the virtual filesystem data when in a pthread or a Wasm Worker context.
632651 var isPthread = typeof ENVIRONMENT_IS_PTHREAD != 'undefined' && ENVIRONMENT_IS_PTHREAD;
633652 var isWasmWorker = typeof ENVIRONMENT_IS_WASM_WORKER != 'undefined' && ENVIRONMENT_IS_WASM_WORKER;
634653 if (isPthread || isWasmWorker) return;\n '''
635654
636655 if options .support_node :
637656 ret += " var isNode = typeof process === 'object' && typeof process.versions === 'object' && typeof process.versions.node === 'string';\n "
657+
658+ if options .support_node and options .export_es6 :
659+ ret += '''if (isNode) {
660+ const { createRequire } = await import('module');
661+ /** @suppress{duplicate} */
662+ var require = createRequire(import.meta.url);
663+ }\n '''
664+
665+ if options .export_es6 :
666+ ret += 'return new Promise((loadDataResolve, loadDataReject) => {\n '
638667 ret += ' async function loadPackage(metadata) {\n '
639668
640669 code = '''
@@ -688,6 +717,10 @@ def generate_js(data_target, data_files, metadata):
688717 Module['FS_createDataFile'](this.name, null, byteArray, true, true, true);
689718 Module['removeRunDependency'](`fp ${that.name}`);'''
690719
720+ finish_handler = create_preloaded if options .use_preload_plugins else create_data
721+ if options .export_es6 :
722+ finish_handler += '\n loadDataResolve();'
723+
691724 if not options .lz4 :
692725 # Data requests - for getting a block of data out of the big archive - have
693726 # a similar API to XHRs
@@ -720,11 +753,18 @@ def generate_js(data_target, data_files, metadata):
720753 var files = metadata['files'];
721754 for (var i = 0; i < files.length; ++i) {
722755 new DataRequest(files[i]['start'], files[i]['end'], files[i]['audio'] || 0).open('GET', files[i]['filename']);
723- }\n ''' % ( create_preloaded if options . use_preload_plugins else create_data )
756+ }\n ''' % finish_handler
724757
725758 if options .has_embedded and not options .obj_output :
726759 diagnostics .warn ('--obj-output is recommended when using --embed. This outputs an object file for linking directly into your application is more efficient than JS encoding' )
727760
761+ catch_handler = ''
762+ if options .export_es6 :
763+ catch_handler += '''
764+ .catch((error) => {
765+ loadDataReject(error);
766+ })'''
767+
728768 for counter , file_ in enumerate (data_files ):
729769 filename = file_ .dstpath
730770 dirname = os .path .dirname (filename )
@@ -1049,10 +1089,10 @@ def generate_js(data_target, data_files, metadata):
10491089 }
10501090 }
10511091 } catch(e) {
1052- await preloadFallback(e);
1092+ await preloadFallback(e)%s ;
10531093 }
10541094
1055- Module['setStatus']?.('Downloading...');\n '''
1095+ Module['setStatus']?.('Downloading...');\n ''' % catch_handler
10561096 else :
10571097 # Not using preload cache, so we might as well start the xhr ASAP,
10581098 # potentially before JS parsing of the main codebase if it's after us.
@@ -1065,15 +1105,16 @@ def generate_js(data_target, data_files, metadata):
10651105 if (!fetched) {
10661106 // Note that we don't use await here because we want to execute the
10671107 // the rest of this function immediately.
1068- fetchRemotePackage(REMOTE_PACKAGE_NAME, REMOTE_PACKAGE_SIZE).then((data) => {
1069- if (fetchedCallback) {
1070- fetchedCallback(data);
1071- fetchedCallback = null;
1072- } else {
1073- fetched = data;
1074- }
1075- })
1076- }\n '''
1108+ fetchRemotePackage(REMOTE_PACKAGE_NAME, REMOTE_PACKAGE_SIZE)
1109+ .then((data) => {
1110+ if (fetchedCallback) {
1111+ fetchedCallback(data);
1112+ fetchedCallback = null;
1113+ } else {
1114+ fetched = data;
1115+ }
1116+ })%s;
1117+ }\n ''' % catch_handler
10771118
10781119 code += '''
10791120 Module['preloadResults'][PACKAGE_NAME] = {fromCache: false};
@@ -1090,10 +1131,10 @@ def generate_js(data_target, data_files, metadata):
10901131 ret += '''
10911132 }
10921133 if (Module['calledRun']) {
1093- runWithFS(Module);
1134+ runWithFS(Module)%s ;
10941135 } else {
10951136 (Module['preRun'] ??= []).push(runWithFS); // FS is not initialized yet, wait for it
1096- }\n '''
1137+ }\n ''' % catch_handler
10971138
10981139 if options .separate_metadata :
10991140 node_support_code = ''
@@ -1131,7 +1172,14 @@ def generate_js(data_target, data_files, metadata):
11311172 }
11321173 loadPackage(%s);\n ''' % json .dumps (metadata )
11331174
1134- ret += '''
1175+ if options .export_es6 :
1176+ ret += '''
1177+ });
1178+ }
1179+ // END the loadDataFile function
1180+ '''
1181+ else :
1182+ ret += '''
11351183 })();\n '''
11361184
11371185 return ret
0 commit comments