Skip to content

Support LoadScript in module-type workers#18144

Merged
sebavan merged 5 commits intoBabylonJS:masterfrom
wmurphyrd:module-worker-support
Apr 8, 2026
Merged

Support LoadScript in module-type workers#18144
sebavan merged 5 commits intoBabylonJS:masterfrom
wmurphyrd:module-worker-support

Conversation

@wmurphyrd
Copy link
Copy Markdown
Contributor

Workers with type: "module" cannot use importScripts, so this falls back to import to allow use of NullEngine (specifically, loading compressed glbs which triggers this LoadScript call) in module workers

Fixes https://forum.babylonjs.com/t/cannot-load-gltf-model-in-a-module-type-web-worker-due-to-importscripts-dependency/62764

@deltakosh deltakosh requested review from RaananW and ryantrem March 20, 2026 18:33
Copy link
Copy Markdown
Member

@RaananW RaananW left a comment

Choose a reason for hiding this comment

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

Thanks for the PR! The problem is real and the fix direction makes sense — module workers define importScripts but throw when you call it, so we need a fallback. A couple of suggestions to tighten this up:

Avoid new Function() — it's essentially eval() and will be blocked under strict CSP policies. There's no need for the indirection here; a plain import(scriptUrl) with a variable argument is already dynamic, and bundlers won't try to resolve it statically. If you want to be extra cautious you can add /* webpackIgnore: true */ inside the import call, but we prefer not to have bundle-specific code in core.

Drop the message sniffing — checking e.message.includes("importScripts") is fragile across browsers (Chrome, Firefox, Safari all word the error differently, and it can change between versions). The good news is instanceof TypeError alone is already a reliable discriminator: when importScripts fails due to a network error or a bad script it throws a DOMException/NetworkError, not a TypeError. A TypeError specifically means the function is unavailable or disabled, which is exactly the module worker case. So you can simplify to just:

(note - edited to add /* webpackIgnore: true */)

} catch (e) {
    if (e instanceof TypeError) {
        /* webpackIgnore: true */ import(scriptUrl).then(
            () => onSuccess?.(),
            (importError) => onError?.(`Unable to load script '${scriptUrl}' in worker`, importError)
        );
    } else {
        onError?.(`Unable to load script '${scriptUrl}' in worker`, e);
    }
}

This way there's no eval, no string matching, and no eslint disables needed. One thing worth noting in the PR description is that this changes the timing from synchronous (importScripts) to asynchronous (import()) in the module worker case — but since the callers already use the callback/promise pattern, that should be fine.

@wmurphyrd
Copy link
Copy Markdown
Contributor Author

@ryantrem - what do you think of @RaananW's comments on the use of new Function that you recommended here?

sebavan

This comment was marked as duplicate.

Comment thread packages/dev/core/src/Misc/tools.ts
@sebavan
Copy link
Copy Markdown
Member

sebavan commented Mar 23, 2026

/azp run

@sebavan sebavan enabled auto-merge (squash) March 23, 2026 15:23
@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 1 pipeline(s).

@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented Mar 23, 2026

Please make sure to label your PR with "bug", "new feature" or "breaking change" label(s).
To prevent this PR from going to the changelog marked it with the "skip changelog" label.

@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented Mar 23, 2026

Reviewer - this PR has made changes to one or more package.json files.

@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented Mar 23, 2026

Snapshot stored with reference name:
refs/pull/18144/merge

Test environment:
https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/refs/pull/18144/merge/index.html

To test a playground add it to the URL, for example:

https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/refs/pull/18144/merge/index.html#WGZLGJ#4600

Links to test your changes to core in the published versions of the Babylon tools (does not contain changes you made to the tools themselves):

https://playground.babylonjs.com/?snapshot=refs/pull/18144/merge
https://sandbox.babylonjs.com/?snapshot=refs/pull/18144/merge
https://gui.babylonjs.com/?snapshot=refs/pull/18144/merge
https://nme.babylonjs.com/?snapshot=refs/pull/18144/merge

To test the snapshot in the playground with a playground ID add it after the snapshot query string:

https://playground.babylonjs.com/?snapshot=refs/pull/18144/merge#BCU1XR#0

If you made changes to the sandbox or playground in this PR, additional comments will be generated soon containing links to the dev versions of those tools.

@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented Mar 23, 2026

Smart Filters Editor is available to test at:
https://sfe.babylonjs.com/?snapshot=refs/pull/18144/merge

@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented Mar 23, 2026

@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented Mar 23, 2026

@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented Mar 23, 2026

@ryantrem
Copy link
Copy Markdown
Member

@ryantrem - what do you think of @RaananW's comments on the use of new Function that you recommended here?

Chatted with @RaananW and his thought is that the potential CSP problem is worse than the problem of polluting the codebase with bundler specific directives, so let's go back to the bundler directive idea. Sorry for the confusion!

@ryantrem
Copy link
Copy Markdown
Member

Don't we still need the WebPack directive so there is not a warning by default?

@sebavan
Copy link
Copy Markdown
Member

sebavan commented Apr 1, 2026

@wmurphyrd any update on the PR ?

@ryantrem
Copy link
Copy Markdown
Member

ryantrem commented Apr 8, 2026

/azp run

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 1 pipeline(s).

@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented Apr 8, 2026

Reviewer - this PR has made changes to one or more package.json files.

@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented Apr 8, 2026

@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented Apr 8, 2026

@bjsplat
Copy link
Copy Markdown
Collaborator

bjsplat commented Apr 8, 2026

@sebavan sebavan merged commit 04ecc1f into BabylonJS:master Apr 8, 2026
20 of 22 checks passed
ryantrem added a commit to ryantrem/Babylon.js that referenced this pull request Apr 8, 2026
@ryantrem ryantrem mentioned this pull request Apr 8, 2026
ryantrem added a commit that referenced this pull request Apr 8, 2026
PR #18144 introduced a dynamic import of a variable, which bundlers
cannot "erase" even when you disable code splitting. These leaves the
`import` expression as is, and dynamic imports are not supported in
Babylon Native, so it causes a syntax error when loading the Babylon.js
bundle. For now, we need to revert this change until we find another
solution (probably either factoring the code in a way that the browser
based script loading can be tree shaken for native, or dynamic imports
are supported in native, or something else).
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.

5 participants