Skip to content
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

Emit bundler-friendly URL locators #14135

Merged
merged 5 commits into from
May 11, 2021
Merged

Emit bundler-friendly URL locators #14135

merged 5 commits into from
May 11, 2021

Conversation

RReverser
Copy link
Collaborator

@RReverser RReverser commented May 10, 2021

This PR changes loading of main Wasm binary as well as helper Worker used by PThread integration to use a URL expression that can be both used directly by browsers as well as statically detected by bundlers like Webpack.

The main caveats are:

  1. Emscripten is very configurable, so some of the new conditions might look odd but are necessary to keep backward compatibility and allow overriding bundler-friendly URL with a custom one during runtime.
  2. None of Closure, our fork of Terser, or even eval (which is used by Emscripten's JS library preprocessing) support import.meta expressions without more work. While Closure seems to have just implemented such support, and it wouldn't be too hard to add it to our Terser too, eval usage would still require a string replacement before execution (or complete revamp).
    To keep implementation simple, for now I went with just string replacement that covers all tools - this way, we replace import.meta -> EMSCRIPTEN$IMPORT$META only once when JS is added before any of this tooling is executed, and then replace back after everything is done right before the final emit.
    We might want to revisit this in future, but for now this works well and covers all the tooling incompatibilities together.
  3. This won't work in Node.js, since it's not compatible with EXPORT_ES6 in general yet.
  4. I've only updated places for loading main Wasm binary and PThread code. This should cover majority of use-cases, but other external files like side modules, proxy-to-pthread, proxy-to-worker, external memory loading etc. are not covered by this PR and need to be updated separately if someone wants them to work with bundlers out of the box too.

Fixes #13571.

emcc.py Outdated Show resolved Hide resolved
emcc.py Outdated Show resolved Hide resolved
emcc.py Outdated Show resolved Hide resolved
src/worker.js Outdated Show resolved Hide resolved
src/worker.js Outdated Show resolved Hide resolved
@RReverser
Copy link
Collaborator Author

RReverser commented May 10, 2021

The failing test is interesting btw - I saw it failing locally, then reproduced it failing even without my changes, yet I see that it worked on CI on the last commit on main branch... I guess I'll need to look deeper :/ Fixed.

emcc.py Outdated Show resolved Hide resolved
RReverser added a commit that referenced this pull request May 10, 2021
These changes are extracted out of #14135 as per @sbc100's request and they make worker.js compliant with strict mode, as well as simplify the Node.js adapter code.
RReverser added 4 commits May 10, 2021 18:39
This PR changes loading of main Wasm binary as well as helper Worker used by PThread integration to use a URL expression that can be both used directly by browsers as well as statically detected by bundlers like Webpack.

The main caveats are:
1. Emscripten is very configurable, so some of the new conditions might look odd but are necessary to keep backward compatibility and allow overriding bundler-friendly URL with a custom one during runtime.
2. None of Closure, our fork of Terser, and `eval` (which is used by Emscripten's JS library preprocessing) support `import.meta` expressions without more work. While Closure seems to have _just_ implemented such support, and it wouldn't be too hard to add it to our Terser too, `eval` usage would still require a string replacement before execution (or complete revamp).
  To keep implementation simple, for now I went with just string replacement that covers all tools - this way, we replace `import.meta` -> `EMSCRIPTEN$IMPORT$META` only once per library when JS is added before any of this tooling is executed, and then replace back after everything is done right before the final emit.
  We might want to revisit this in future, but for now this works well and covers all the tooling incompatibilities together.
3. Webpack assumes that all modules are strict mode, so I updated `worker.js` correspondingly to avoid usages of global `this` (which is `undefined` in strict mode and breaks in bundled code) and instead using `self`; I've also updated the Node.js adapter code to satisfy strict requirements too and to be a bit simpler.
4. This won't work in Node.js, since it's not compatible with `EXPORT_ES6` in general yet.
5. I've only updated places for loading main Wasm binary and PThread code. This should cover majority of use-cases, but other external files like side modules, proxy-to-pthread, proxy-to-worker, external memory loading etc. are not covered by this PR and need to be updated separately if someone wants them to work with bundlers out of the box too.

Fixes #13571.
Copy link
Collaborator

@sbc100 sbc100 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm % nits

emcc.py Outdated Show resolved Hide resolved
emcc.py Show resolved Hide resolved
@sbc100
Copy link
Collaborator

sbc100 commented May 10, 2021

PR description could use an update now that (3) landed separately. Otherwise feel free to land.

@RReverser
Copy link
Collaborator Author

PR description could use an update now that (3) landed separately. Otherwise feel free to land.

Updated!

@RReverser RReverser merged commit 3f0c7e9 into main May 11, 2021
@RReverser RReverser deleted the bundler-friendly branch May 11, 2021 11:20
RReverser added a commit that referenced this pull request May 11, 2021
During review of #14135 some of the changes made TARGET_JS_NAME to be a relative path instead of a basename.

This way, when someone specified `-pthread -o out.js`, it worked fine, but if someone used `-pthread -o nested/dir/out.js` then the `nested/dir/out.worker.js` would have a reference to `./nested/dir/out.js` not to `./out.js` as it should for a file alongside it.
Copy link
Member

@kripken kripken left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work @RReverser !

RReverser added a commit that referenced this pull request May 20, 2021
`Module['locateFile']` needs to be checked even in `EXPORT_ES6` mode.

In #14135 I did this for `new Worker`, but not for Wasm binary locator, so it broke existing usages of EXPORT_ES6 + custom `locateFile` function.
sbc100 pushed a commit that referenced this pull request May 21, 2021
`Module['locateFile']` needs to be checked even in `EXPORT_ES6` mode.

In #14135 I did this for `new Worker`, but not for Wasm binary locator, so it broke existing usages of EXPORT_ES6 + custom `locateFile` function.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Emit bundler-friendly URL locators
3 participants