Skip to content

RFE: ability to elide the automatic "export default ..." for ES6 module builds #18237

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
sgbeal opened this issue Nov 20, 2022 · 3 comments
Open

Comments

@sgbeal
Copy link

sgbeal commented Nov 20, 2022

When building an ES6 module, Emscripten automatically adds:

export default myModuleInitFunction;

to the resulting JS file. "The problem" with that is that we (the sqlite project) have to, due in part to #18071, overwrite the module init function object with a modified one. We do this via --extern-post-js and then want to do:

export default ourModifiedInitFunction;

but it's illegal to do "export default" twice in the same module.

Our current workaround is this bit of hackery in our makefile after compiling sqlite3.mjs:

	@if [ esm = $(1) ]; then \
		echo "Fragile workaround for an Emscripten annoyance. See emcc.flags.sqlite3.esm."; \
		sed -i -e '0,/^export default/{/^export default/d}' $@ || exit $$?; \
		if ! grep -q '^export default' $@; then \
			echo "Cannot find export default." 1>&2; \
			exit 1; \
		fi; \
	fi

i.e. we delete the first "export default" line, leaving ours intact. That's horribly fragile.

Sidebar: the auto-injected "export default" line does not include a newline after it, which causes --extern-post-js to be appended starting on that same line, which requires a separate kludge on our side to account for.

What would be really useful is a way to tell emcc to not add the "export default" line automatically. When building an .mjs file it automatically does so even if -sEXPORT_ES6=0 is used. An alternative implementation would be to not add that line when -sEXPORT_ES6=0, but whether or not that would have other side effects is a question i cannot answer.

@simonbuehler
Copy link

when building opencv.js with "export default --build_flags="-s EXPORT_ES6=1 " also this code gets generated:

var cv = (() => {
  var _scriptDir = import.meta.url;
  
  return (
async function(moduleArg = {}) {

function GROWABLE_HEAP_I8(){if(wasmMemory.buffer!=HEAP8.buffer){updateMemoryViews()}return HEAP8}funct ......

  return moduleArg.ready
}
);
})();
;
export default cv;
  if (typeof Module === 'undefined')
    Module = {};
  return cv(Module);
}));
        

here two problems do exist:

  • export default cv; is invalid at this position, should be last line in file ( outer scope)
  • Module = {}; should be varModule = {}; so vite does accept the build

@sbc100
Copy link
Collaborator

sbc100 commented Dec 4, 2023

@sgbeal could you say more about why you need to overwrite the module init function object with a modified one?

@sgbeal
Copy link
Author

sgbeal commented Dec 4, 2023

@sgbeal could you say more about why you need to overwrite the module init function object with a modified one?

That's described in #18071.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants