Skip to content

Commit 43a85a3

Browse files
authored
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 sql-js#524
1 parent ee67aeb commit 43a85a3

File tree

3 files changed

+74
-2
lines changed

3 files changed

+74
-2
lines changed

Makefile

+14-2
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

+10
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

+50
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)