Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 43a85a3

Browse files
authoredApr 12, 2025··
Create ESM build
I do not sure that I will understand whole impact on the EMCC modularization, but at least these fixes in the modularization works for me in the Blazor applciation, which is by itself ESM environment. closes #524
1 parent ee67aeb commit 43a85a3

File tree

3 files changed

+74
-2
lines changed

3 files changed

+74
-2
lines changed
 

‎Makefile

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ EXPORTED_METHODS_JSON_FILES = src/exported_functions.json src/exported_runtime_m
7373
all: optimized debug worker
7474

7575
.PHONY: debug
76-
debug: dist/sql-asm-debug.js dist/sql-wasm-debug.js
76+
debug: dist/sql-asm-debug.js dist/sql-wasm-debug.js dist/sql-wasm-esm-debug.js
7777

7878
dist/sql-asm-debug.js: $(BITCODE_FILES) $(OUTPUT_WRAPPER_FILES) $(SOURCE_API_FILES) $(EXPORTED_METHODS_JSON_FILES)
7979
$(EMCC) $(EMFLAGS) $(EMFLAGS_DEBUG) $(EMFLAGS_ASM) $(BITCODE_FILES) $(EMFLAGS_PRE_JS_FILES) -o $@
@@ -87,8 +87,14 @@ dist/sql-wasm-debug.js: $(BITCODE_FILES) $(OUTPUT_WRAPPER_FILES) $(SOURCE_API_FI
8787
cat src/shell-pre.js out/tmp-raw.js src/shell-post.js > $@
8888
rm out/tmp-raw.js
8989

90+
dist/sql-wasm-esm-debug.js: $(BITCODE_FILES) $(OUTPUT_WRAPPER_FILES) $(SOURCE_API_FILES) $(EXPORTED_METHODS_JSON_FILES)
91+
$(EMCC) $(EMFLAGS) $(EMFLAGS_DEBUG) $(EMFLAGS_WASM) $(BITCODE_FILES) $(EMFLAGS_PRE_JS_FILES) -o $@
92+
mv $@ out/tmp-raw.js
93+
cat src/shell-pre-esm.js out/tmp-raw.js src/shell-post-esm.js > $@
94+
rm out/tmp-raw.js
95+
9096
.PHONY: optimized
91-
optimized: dist/sql-asm.js dist/sql-wasm.js dist/sql-asm-memory-growth.js
97+
optimized: dist/sql-asm.js dist/sql-wasm.js dist/sql-wasm-esm.js dist/sql-asm-memory-growth.js
9298

9399
dist/sql-asm.js: $(BITCODE_FILES) $(OUTPUT_WRAPPER_FILES) $(SOURCE_API_FILES) $(EXPORTED_METHODS_JSON_FILES)
94100
$(EMCC) $(EMFLAGS) $(EMFLAGS_OPTIMIZED) $(EMFLAGS_ASM) $(BITCODE_FILES) $(EMFLAGS_PRE_JS_FILES) -o $@
@@ -102,6 +108,12 @@ dist/sql-wasm.js: $(BITCODE_FILES) $(OUTPUT_WRAPPER_FILES) $(SOURCE_API_FILES) $
102108
cat src/shell-pre.js out/tmp-raw.js src/shell-post.js > $@
103109
rm out/tmp-raw.js
104110

111+
dist/sql-wasm-esm.js: $(BITCODE_FILES) $(OUTPUT_WRAPPER_FILES) $(SOURCE_API_FILES) $(EXPORTED_METHODS_JSON_FILES)
112+
$(EMCC) $(EMFLAGS) $(EMFLAGS_OPTIMIZED) $(EMFLAGS_WASM) $(BITCODE_FILES) $(EMFLAGS_PRE_JS_FILES) -o $@
113+
mv $@ out/tmp-raw.js
114+
cat src/shell-pre-esm.js out/tmp-raw.js src/shell-post-esm.js > $@
115+
rm out/tmp-raw.js
116+
105117
dist/sql-asm-memory-growth.js: $(BITCODE_FILES) $(OUTPUT_WRAPPER_FILES) $(SOURCE_API_FILES) $(EXPORTED_METHODS_JSON_FILES)
106118
$(EMCC) $(EMFLAGS) $(EMFLAGS_OPTIMIZED) $(EMFLAGS_ASM_MEMORY_GROWTH) $(BITCODE_FILES) $(EMFLAGS_PRE_JS_FILES) -o $@
107119
mv $@ out/tmp-raw.js

‎src/shell-post-esm.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
2+
3+
// The shell-pre.js and emcc-generated code goes above
4+
return Module;
5+
}); // The end of the promise being returned
6+
7+
return initSqlJsPromise;
8+
} // The end of our initSqlJs function
9+
10+
export = initSqlJs;

‎src/shell-pre-esm.js

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
2+
// We are modularizing this manually because the current modularize setting in Emscripten has some issues:
3+
// https://github.com/kripken/emscripten/issues/5820
4+
// In addition, When you use emcc's modularization, it still expects to export a global object called `Module`,
5+
// which is able to be used/called before the WASM is loaded.
6+
// The modularization below exports a promise that loads and resolves to the actual sql.js module.
7+
// That way, this module can't be used before the WASM is finished loading.
8+
9+
// We are going to define a function that a user will call to start loading initializing our Sql.js library
10+
// However, that function might be called multiple times, and on subsequent calls, we don't actually want it to instantiate a new instance of the Module
11+
// Instead, we want to return the previously loaded module
12+
13+
// TODO: Make this not declare a global if used in the browser
14+
var initSqlJsPromise = undefined;
15+
16+
var initSqlJs = function (moduleConfig) {
17+
18+
if (initSqlJsPromise){
19+
return initSqlJsPromise;
20+
}
21+
// If we're here, we've never called this function before
22+
initSqlJsPromise = new Promise(function (resolveModule, reject) {
23+
24+
// We are modularizing this manually because the current modularize setting in Emscripten has some issues:
25+
// https://github.com/kripken/emscripten/issues/5820
26+
27+
// The way to affect the loading of emcc compiled modules is to create a variable called `Module` and add
28+
// properties to it, like `preRun`, `postRun`, etc
29+
// We are using that to get notified when the WASM has finished loading.
30+
// Only then will we return our promise
31+
32+
// If they passed in a moduleConfig object, use that
33+
// Otherwise, initialize Module to the empty object
34+
var Module = typeof moduleConfig !== 'undefined' ? moduleConfig : {};
35+
36+
// EMCC only allows for a single onAbort function (not an array of functions)
37+
// So if the user defined their own onAbort function, we remember it and call it
38+
var originalOnAbortFunction = Module['onAbort'];
39+
Module['onAbort'] = function (errorThatCausedAbort) {
40+
reject(new Error(errorThatCausedAbort));
41+
if (originalOnAbortFunction){
42+
originalOnAbortFunction(errorThatCausedAbort);
43+
}
44+
};
45+
46+
Module['postRun'] = Module['postRun'] || [];
47+
Module['postRun'].push(function () {
48+
// When Emscripted calls postRun, this promise resolves with the built Module
49+
resolveModule(Module);
50+
});

0 commit comments

Comments
 (0)
Please sign in to comment.