Skip to content

Remove USE_ES6_IMPORT_META setting #23171

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

Merged
merged 1 commit into from
Feb 21, 2025

Conversation

sbc100
Copy link
Collaborator

@sbc100 sbc100 commented Dec 15, 2024

This setting was added (IIUC) as a temporary workaround for the lack or support for import.meta in browser and tooling.

However import.meta has been at stage 4 for almost 5 years now: tc39/proposal-import-meta#21

Webback (released in 2020) also has builtin support for import.meta, so I would hope the use case for disabling this setting no longer exists.

See #9234 and #8729

@@ -44,7 +44,7 @@ export function processMacros(text, filename) {
// Also handles #include x.js (similar to C #include <file>)
export function preprocess(filename) {
let text = read(filename);
if (EXPORT_ES6 && USE_ES6_IMPORT_META) {
if (EXPORT_ES6) {
// `eval`, Terser and Closure don't support module syntax; to allow it,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Potential follow up: I'm pretty sure closure supports module syntax now. Not sure about terser.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I looked into this and will try to come up with followup. For now is seems like the eval phase is the one were we still need this.

@sbc100 sbc100 force-pushed the USE_ES6_IMPORT_META branch 3 times, most recently from 2a546ac to 79f3fef Compare December 18, 2024 02:40
@sbc100 sbc100 closed this Jan 3, 2025
@sbc100 sbc100 deleted the USE_ES6_IMPORT_META branch January 3, 2025 22:45
@sbc100 sbc100 restored the USE_ES6_IMPORT_META branch January 3, 2025 23:00
@sbc100 sbc100 reopened this Jan 3, 2025
@kleisauke
Copy link
Collaborator

FWIW, Cloudflare Workers doesn't support import.meta at the moment, see: cloudflare/workerd#2963.

That said, I don't think that should block this PR, since users can simply omit -sEXPORT_ES6 if they need to deploy there.

@sbc100
Copy link
Collaborator Author

sbc100 commented Feb 7, 2025

FWIW, Cloudflare Workers doesn't support import.meta at the moment, see: cloudflare/workerd#2963.

That said, I don't think that should block this PR, since users can simply omit -sEXPORT_ES6 if they need to deploy there.

Or presumably one could just use a bundler before deploying to cloudflare? Which seems like a likely/good choice anyway, right?

@sbc100 sbc100 force-pushed the USE_ES6_IMPORT_META branch from 79f3fef to 4800608 Compare February 20, 2025 23:07
This setting was added (IIUC) as a temporary workaround for the lack or
support for `import.meta` in browser and tooling.

However `import.meta` has been at stage 4 for almost 5 years now:
tc39/proposal-import-meta#21

Webback (released in 2020) also has builtin support for `import.meta`,
so I would hope the use case for disabling this setting no longer
exists.

See emscripten-core#9234 and emscripten-core#8729
@sbc100 sbc100 force-pushed the USE_ES6_IMPORT_META branch from 4800608 to 8d46778 Compare February 20, 2025 23:09
@sbc100 sbc100 enabled auto-merge (squash) February 21, 2025 20:40
@sbc100 sbc100 merged commit de54d21 into emscripten-core:main Feb 21, 2025
29 checks passed
@sbc100 sbc100 deleted the USE_ES6_IMPORT_META branch February 21, 2025 20:43
@JoeOsborn
Copy link
Contributor

This fix breaks cross-origin workers via mainScriptUrlOrBlob. Since the worker script is now hard-coded as the URL, we don't have the ability to use an inline worker to importScripts or use a downloaded blob.

@dlemstra
Copy link
Contributor

dlemstra commented Mar 4, 2025

I was using this option for a use case that was probably not the intention of this option. I used this option to avoid a bundler from embedding the wasm file. And without this option I now need to find a way in the tooling that uses the output to avoid inlining new URL('{{{ WASM_BINARY_FILE }}}', import.meta.url).href as new URL("data:application/wasm;base64,. I am using Module['locateFile'] and Module['wasmBinary'] to give control to the user of my library where to load the .wasm from. So for me it would still be nice to have an option to disable this or only allow the usage of locateFile and wasmBinary. But I can also understand that this would not be something that the team wants to maintain.

For those who are reading this in the future I use the following "hack" to work around this issue. Replace new URL('myfile.wasm', import.meta.url).href with new URL('myfile.wasm.empty', import.meta.url).href after the output is generated and add an empty file myfile.wasm.empty (replace myfile with the name of your wasm file). This will of course prevent that part from working so you will need to either set locateFile or wasmBinary to fix the loading of the wasm data.

@sbc100
Copy link
Collaborator Author

sbc100 commented Mar 4, 2025

Interesting. It does sounds odd that this would be the option used to prevent the bundler from embedding the wasm. Can I ask what bundler you are using? Have you looked for a blunder setting that might avoid this?

@dlemstra
Copy link
Contributor

dlemstra commented Mar 5, 2025

I am using vite 6 that is using rollup as it's bundler and I have tried using several of the suggested options for this but none of them seemed to work for my project.

@sbc100
Copy link
Collaborator Author

sbc100 commented Mar 5, 2025

Is there an open bug again vite for that? It certainly seems like a bundler bug/feature, rather than something emscripten should be having to deal with.

@dlemstra
Copy link
Contributor

dlemstra commented Mar 6, 2025

I have not found a bug about that so I will probably need to report one. But that will probably take me some time to create something that can be used to reproduce it. And the work around can be a possible "fix/hack" when someone else also has a problem with their bundler.

sbc100 pushed a commit that referenced this pull request Mar 15, 2025
Spun out from #23804 .

This is a fix for #23769 which was introduced by #23171 , where the use
of the bundler pattern hard-coding a script name was made to apply to
all ES6 exports.

`mainScriptUrlOrBlob` is necessary under es6 exports to support running
a threaded emscripten module from another origin, e.g. to distribute an
emscripten module on a CDN (the script will load for the main thread but
won’t be allowed to create workers). Using blobs is an effective
workaround.
buzz added a commit to buzz/mediainfo.js that referenced this pull request Apr 2, 2025
@Sec-ant
Copy link

Sec-ant commented Apr 14, 2025

I have exactly the same use case as what @dlemstra mentioned above for USE_ES6_IMPORT_META in one of my project, I also let users to use locateFile to override the wasm serve path. I ended up patching the preamble.js file to restore the old behavior, which is far from graceful but yields the expected output. I also use vite 6 to bundle my project.

@jinwuwu001
Copy link

Removing USE_ES6_IMPORT_META will result in library users being unable to customize the loading location of .js when using multi-threaded .wasm.
The multi-threaded .js code obtained when USE_ES6_IMPORT_META=0 is as follows:

// emsdk 4.0.1
allocateUnusedWorker() {
  var worker;
  var workerOptions = { type: "module", name: "em-pthread" };
  var pthreadMainJs = _scriptName;
  if (Module["mainScriptUrlOrBlob"]) {
    pthreadMainJs = Module["mainScriptUrlOrBlob"];
    if (typeof pthreadMainJs != "string") {
      pthreadMainJs = URL.createObjectURL(pthreadMainJs);
    }
  }
  worker = new Worker(pthreadMainJs, workerOptions);
  PThread.unusedWorkers.push(worker);
}

Users can set the loading location through mainScriptUrlOrBlob

const moduleConfig = {
  locateFile: (file: string) => {
    const path = `${demoDir}.wasm`;
    return path;
  },
  mainScriptUrlOrBlob: `${demoDir}.js`
};

The multi-threaded .js code obtained when USE_ES6_IMPORT_META=1 is as follows:

// emsdk 4.0.4
allocateUnusedWorker() {
  var worker;
  worker = new Worker(new URL("demo.js", import.meta.url), { type: "module", name: "em-pthread" });
  PThread.unusedWorkers.push(worker);
}

At this time, users can only load files from the following path

`{import.meta.url}/demo.js`

Cannot load files from the specified location unless manually modifying demo.js
for example:

`{import.meta.url}/dir1/demo.js`
`{import.meta.url}/dir1/dir2/demo.js`
`{import.meta.url}/dir1/dir2/dir3/demo.js`

How to customize the loading location after removing USE_ES6_IMPORT_META
It is necessary to customize the loading position in the scenario of dynamically loading .wasm

@kleisauke
Copy link
Collaborator

@jinwuwu001 Could you re-test with Emscripten 4.0.6 or later? I think your use-case was fixed via commit 9e21488.

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.

8 participants