Skip to content

Playground: bundle babylonjs-addons + polyfill ES2019/ES2022 gaps on Chakra#1700

Open
bkaradzic-microsoft wants to merge 3 commits into
BabylonJS:masterfrom
bkaradzic-microsoft:fix-bn-playground-polyfills
Open

Playground: bundle babylonjs-addons + polyfill ES2019/ES2022 gaps on Chakra#1700
bkaradzic-microsoft wants to merge 3 commits into
BabylonJS:masterfrom
bkaradzic-microsoft:fix-bn-playground-polyfills

Conversation

@bkaradzic-microsoft
Copy link
Copy Markdown
Contributor

Three small, self-contained Playground-side fixes:

1. ES2022 Error(message, options) polyfill for Chakra

Chakra's built-in Error constructor predates ES2022 and treats its second
argument as part of the message: new Error("hello", { cause: 42 }) produces
an Error whose .message is "[object Object]" and whose .cause is
undefined. Babylon.js's shader-compile error rethrow uses this signature,
so on every Chakra-based BN backend (the Win32 default) real
glslang/SPIRV-Cross diagnostics surface in stdout as
Error: [object Object] with no further detail, hiding the actual error.

Apps/Playground/Scripts/error_polyfill.js is loaded before any other
script. It self-detects ES2022 support (no-op on V8 / modern JSC) and on
Chakra patches Error plus the six standard subclasses (TypeError,
RangeError, SyntaxError, ReferenceError, URIError, EvalError)
with a thin wrapper that forwards the message string and attaches
cause via Object.defineProperty. Uses Reflect.construct to preserve
new.target, so class X extends Error { ... } keeps the correct
prototype chain.

Verified end-to-end on Chakra (build/win32 = NAPI_JAVASCRIPT_ENGINE=Chakra):
On a known shader-compile failure scenario the captured error transforms from
BJS - Error: [object Object] to
BJS - Error: SHADER ERROR\nERROR: 2 compilation errors. No code generated.
i.e. the actual glslang diagnostic now reaches stdout.

2. ES2019 String.prototype.trimEnd polyfill for Chakra

Chakra predates ES2019 and only implements the older trimLeft / trimRight.
Babylon.js's ShaderProcessor and NodeMaterial paths call trimEnd, so
on Chakra those paths throw TypeError: Object doesn't support property or method 'trimEnd'.

Apps/Playground/Scripts/string_polyfill.js aliases
String.prototype.trimEnd -> trimRight and trimStart -> trimLeft when the
ES2019 names are missing. Both pairs are spec-standard aliases, so engines
that already provide the modern names are untouched.

Verified: Merge Meshes with submeshes and Bones and morphs computation order now validate; the 'trimEnd' error is gone from the other three
known affected tests (which now fail for unrelated reasons tracked elsewhere).

3. Bundle babylonjs-addons in Playground

Babylon Native ships babylonjs, babylonjs-gui, babylonjs-loaders,
babylonjs-materials, and babylonjs-serializers alongside its Playground
app but not babylonjs-addons. The addons package hosts newer Babylon.js
components (Atmosphere, LiquidRenderingSceneComponent, ...) under the
global ADDONS namespace, so any Playground snippet that uses them throws
ReferenceError: 'ADDONS' is not defined.

Add the npm dependency, ship babylonjs.addons.js as a Playground resource
via BABYLON_SCRIPTS, and load it right after babylon.max.js so the
addons initialization sees a fully constructed BABYLON global.

Verified: all four Atmosphere snippets (Sunset, Night,
Night (Planet Origin), Space View) no longer throw the ADDONS
ReferenceError. They still fail on a separate Texture layers are not supported in Babylon Native (3D-texture / NativeEngine gap, tracked
separately) but the ADDONS-bundling fix is independently complete.

Risk

  • Polyfills are no-ops on engines that already implement the standard
    behaviour (V8 / modern JSC), so the V8 / JSC / iOS / macOS / Android paths
    are unchanged.
  • babylonjs-addons only adds one more LoadScript call; the npm package
    is in the same release line (^9.3.4) as the other Babylon scripts the
    Playground already ships.
  • All three changes are in the Playground app only; no engine / plugin code
    is touched.

Smoke regression check

Five known-passing indices (0, 39, 47, 165, 200) produce the same
exit code / pass count as upstream/master after this branch.

Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com

Chakra's built-in Error constructor predates ES2022. When called with
`new Error("msg", { cause: e })` it stringifies the options bag into
.message ("[object Object]") and never sets .cause. Babylon.js v6+
uses this signature in its shader-compile error rethrow, so on every
Chakra-based BN backend (the Win32 default) a real glslang/SPIRV-Cross
error surfaces in stdout as `Error: [object Object]` with no further
detail, hiding the actual diagnostic.

Add a small JS polyfill loaded before any other script that:
- Probes ES2022 support via `new Error("x", {cause: 42})` and returns
  early on engines that already implement the spec (V8, modern JSC).
- Replaces Error and the six standard subclasses with a thin wrapper
  that forwards the message string and attaches `cause` from the
  options bag via Object.defineProperty (non-enumerable, matches V8
  semantics).
- Uses Reflect.construct to preserve `new.target` so subclassing via
  `class X extends Error { ... }` keeps the correct prototype chain.
Chakra predates ES2019 and only implements the older trimLeft / trimRight
names. Babylon.js's ShaderProcessor and NodeMaterial code paths use the
newer trimEnd name, so on Chakra-based BN backends those paths fail with
`TypeError: Object doesn't support property or method 'trimEnd'`.

Add a tiny shim loaded right after error_polyfill.js that aliases
String.prototype.trimEnd -> trimRight and trimStart -> trimLeft when the
ES2019 names are missing. Both pairs are standard aliases in the spec,
so engines that already provide the modern names are not touched.
Babylon Native ships babylonjs, babylonjs-gui, babylonjs-loaders,
babylonjs-materials, and babylonjs-serializers alongside its Playground
app but not babylonjs-addons. The addons package hosts newer Babylon
.js components (Atmosphere, LiquidRenderingSceneComponent, ...) under
the global `ADDONS` namespace, so any Playground snippet that uses
them throws `ReferenceError: 'ADDONS' is not defined`.

Add the npm dependency, ship babylonjs.addons.js as a Playground
resource via BABYLON_SCRIPTS, and load it right after babylon.max.js
so the addons-side initialization sees a fully constructed BABYLON
global.
Copilot AI review requested due to automatic review settings May 16, 2026 00:31
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the Babylon Native Playground to improve compatibility with Chakra-based runtimes and to ship the babylonjs-addons bundle so Playground snippets using the ADDONS global can run.

Changes:

  • Load early JS polyfills for ES2022 Error(message, options) and ES2019 String.prototype.trimStart/trimEnd before Babylon scripts.
  • Add babylonjs-addons to the shipped Playground scripts and load it after babylon.max.js.
  • Add the new polyfill scripts to Playground build packaging and add the npm dependency.

Reviewed changes

Copilot reviewed 5 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
Apps/Playground/Shared/AppContext.cpp Loads the new polyfill scripts first and adds babylonjs.addons.js to the script load order.
Apps/Playground/Scripts/string_polyfill.js Adds Chakra-targeted trimStart/trimEnd alias polyfill.
Apps/Playground/Scripts/error_polyfill.js Adds Chakra-targeted Error(message, options) / cause polyfill for Error and standard subclasses.
Apps/Playground/CMakeLists.txt Packages the new polyfill scripts and adds babylonjs.addons.js to copied/embedded script resources.
Apps/package.json Adds babylonjs-addons dependency.
Apps/package-lock.json Records the resolved babylonjs-addons dependency (currently introducing an additional Babylon.js version).
Files not reviewed (1)
  • Apps/package-lock.json: Language not supported
Comments suppressed due to low confidence (2)

Apps/package.json:18

  • Using ^9.3.4 for babylonjs-addons allows it to resolve to a newer 9.x than the rest of the Babylon packages (and the bundled babylon.max.js). To avoid ABI/API mismatches and duplicate installs, pin babylonjs-addons to the same exact version as babylonjs (or update all Babylon packages together).
  "dependencies": {
    "babylonjs": "^9.3.4",
    "babylonjs-addons": "^9.3.4",
    "babylonjs-gltf2interface": "^9.3.4",
    "babylonjs-gui": "^9.3.4",
    "babylonjs-loaders": "^9.3.4",
    "babylonjs-materials": "^9.3.4",
    "babylonjs-serializers": "^9.3.4",

Apps/package-lock.json:2619

  • This nested node_modules/babylonjs-addons/node_modules/babylonjs entry indicates babylonjs-addons pulled in its own Babylon.js version (9.7.0). If the Playground loads babylon.max.js from the top-level install, this duplication is unnecessary at best and can become a runtime mismatch at worst; aligning package versions should eliminate this nested dependency.

return err;
}

Patched.prototype = Orig.prototype;
Comment thread Apps/package-lock.json
Comment on lines +2611 to +2620
"babylonjs": "9.7.0"
}
},
"node_modules/babylonjs-addons/node_modules/babylonjs": {
"version": "9.7.0",
"resolved": "https://registry.npmjs.org/babylonjs/-/babylonjs-9.7.0.tgz",
"integrity": "sha512-buaBjhIuBCpJNlwG+KUfqTtC0wvVQuK8ruFDcegjObrbPIrYqOp6qVdtqBgGtWrzmvWj4bGpUIQgG6HCwXw2JA==",
"hasInstallScript": true,
"license": "Apache-2.0"
},
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.

2 participants