Skip to content

Relocate deprecated API shims so the ESM engine tree-shakes - #9251

Merged
willeastcott merged 4 commits into
mainfrom
relocate-deprecated-shims-for-tree-shaking
Sep 1, 2026
Merged

Relocate deprecated API shims so the ESM engine tree-shakes#9251
willeastcott merged 4 commits into
mainfrom
relocate-deprecated-shims-for-tree-shaking

Conversation

@willeastcott

Copy link
Copy Markdown
Contributor

Description

Any import from the ESM package currently retains most of the engine: deprecated.js is the one module listed in sideEffects, and its module-scope prototype patches statically import AppBase, StandardMaterial, ForwardRenderer, RigidBodyComponentSystem and more — so bundlers must keep that entire graph even for import { Vec3 } from 'playcanvas'.

This PR moves every prototype-patch shim onto the class it patches, as a regular member with @ignore/@deprecated JSDoc (the existing Entity#getGuid idiom). Each shim now ships only when its class does and behaves identically at runtime. deprecated.js keeps only side-effect-free aliases and helper functions, and package.json now declares "sideEffects": false.

Measured with esbuild (minified), same tree before/after:

Bundle Before After
import { Vec3 } only 882 KB raw / 229 KB gzip (559 modules) 3.2 KB / 1.1 KB (3 modules)
Minimal engine-only cube app 1129 KB / 297 KB gzip 1056 KB / 279 KB gzip
Full namespace (everything used) 2391 KB 2391 KB — unchanged

@playcanvas/react and web-components inherit the win automatically. UMD builds are unaffected (all exports retained, shims applied identically).

Notes for reviewers:

  • Shims with runtime-computed names can't be class members and remain module-scope helper loops (StandardMaterial vertex-color/tint aliases, StandardMaterialOptions litOptions forwarding). These are invisible to tsc, so they don't affect the d.ts.
  • ForwardRenderer#renderComposition is patched from app-base.js because it needs getApplication and scene code must not import from framework.
  • The anisotropy entry is removed from the rollup-types-fixup synthesis list — the real accessor now provides the typing. This also fixes its d.ts doc text, which was previously mis-sliced from anisotropyIntensity's @property doc.
  • Three StandardMaterial setters assign their target properties via Object.assign because tsc declaration emit synthesizes duplicate member declarations from literal this.x = ... assignments to fixup-managed dynamic props.
  • Deprecated members now appear in the d.ts typed and @deprecated-tagged (previously invisible to TypeScript users); @ignore keeps them out of the API docs, as with Entity#getGuid.
  • New canary test in test/bundles/treeshake.test.mjs bundles import { Vec3 } against the built ESM tree and fails above 10 KB, so a future module-scope side effect can't silently regress tree-shaking.

Verified: full unit suite (2337 passing, failures identical to main baseline), all 61 bundle tests (exports parity across all 11 targets, smoke, canary), build:types + test:types, lint, publint, plus a runtime check that all 27 shim behaviors and deprecated exports are unchanged.

Checklist

  • I have read the contributing guidelines
  • My code follows the project's coding standards
  • This PR focuses on a single change

🤖 Generated with Claude Code

deprecated.js was the one module listed in package.json sideEffects, and
its module-scope prototype patches statically imported AppBase,
StandardMaterial, ForwardRenderer, RigidBodyComponentSystem and more. As
a result, any import from the ESM package retained most of the engine:
a Vec3-only app bundled to 882 KB (229 KB gzip).

Each shim now lives on the class it patches as a regular member with
@ignore/@deprecated JSDoc (matching Entity#getGuid), so it ships only
when the class does and behaves identically. Shims with runtime-computed
names (StandardMaterial vertex-color/tint aliases, StandardMaterialOptions
litOptions forwarding) remain module-scope helper loops, and the
ForwardRenderer#renderComposition patch stays in app-base.js because it
needs getApplication and scene code must not import from framework.
deprecated.js keeps only side-effect-free aliases and helper functions,
and package.json now declares sideEffects: false.

Type declarations: the anisotropy entry is removed from the
rollup-types-fixup synthesis list since the real accessor now provides
the typing (this also fixes its doc text, which was mis-sliced from
anisotropyIntensity). Three StandardMaterial setters assign their target
properties via Object.assign because tsc declaration emit synthesizes
duplicate members from literal this.x assignments to fixup-managed props.

A canary test bundles 'import { Vec3 }' against the built ESM tree and
fails if it exceeds 10 KB, so a future module-scope side effect cannot
silently regress tree-shaking.

Measured (esbuild, minified): Vec3-only app 882 KB -> 3.2 KB
(229 KB -> 1.1 KB gzip); minimal engine-only cube app 1129 KB -> 1056 KB
(297 KB -> 279 KB gzip); full-namespace bundle unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Aug 28, 2026

Copy link
Copy Markdown

Build size report

This PR changes the size of the minified bundles.

Bundle Minified Gzip Brotli
playcanvas.min.js 2390.9 KB (−0.8 KB, −0.03%) 614.8 KB (−0.2 KB, −0.04%) 477.0 KB (−0.1 KB, −0.02%)
playcanvas.min.mjs 2388.2 KB (−0.8 KB, −0.03%) 613.5 KB (−0.3 KB, −0.05%) 476.5 KB (−0.1 KB, −0.02%)

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Relocates deprecated API shims to their owning modules, enabling effective ESM tree-shaking while preserving compatibility.

Changes:

  • Moves deprecated prototype shims into class modules.
  • Marks the package side-effect-free and simplifies deprecated.js.
  • Adds a bundle-size regression canary and updates type synthesis.

Reviewed changes

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

Show a summary per file
File Description
package.json Declares all modules side-effect-free.
src/deprecated/deprecated.js Removes prototype patches and heavy imports.
src/framework/app-base.js Hosts legacy app and renderer methods.
src/framework/asset/asset-registry.js Adds the deprecated asset lookup method.
src/framework/components/model/component.js Adds the deprecated visibility method.
src/framework/components/rigid-body/component.js Adds legacy rigid-body members.
src/framework/components/rigid-body/system.js Adds the deprecated gravity method.
src/framework/input/element-input.js Adds the legacy wheel accessor.
src/framework/xr/xr-input-source.js Adds deprecated XR accessors.
src/platform/input/mouse-event.js Adds the legacy wheel accessor.
src/scene/materials/material.js Adds deprecated material accessors.
src/scene/materials/standard-material-options.js Relocates legacy option forwarding.
src/scene/materials/standard-material.js Relocates material aliases and accessors.
test/bundles/treeshake.test.mjs Adds the bundle-size canary.
utils/plugins/rollup-types-fixup.mjs Removes redundant anisotropy synthesis.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/framework/components/rigid-body/system.js
Comment thread test/bundles/treeshake.test.mjs
willeastcott and others added 3 commits September 1, 2026 12:54
Type setGravity's legacy parameter forms so the generated declarations
accept both setGravity(vec) and setGravity(x, y, z), and add a bundled
runtime test proving representative relocated shims (class members,
computed-name aliases, options forwarding, the cross-module
ForwardRenderer patch) survive tree-shaking and still apply.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@willeastcott
willeastcott merged commit a1c8895 into main Sep 1, 2026
10 checks passed
@willeastcott
willeastcott deleted the relocate-deprecated-shims-for-tree-shaking branch September 1, 2026 12:04
willeastcott added a commit that referenced this pull request Sep 4, 2026
… rules (#9296)

AGENTS.md still described the build system as Rollup and referenced a
src/polyfill directory that no longer exists. The JavaScript bundles are
built by esbuild, with Rollup used only to bundle the .d.ts, and the
tree-shaking invariant that the deprecated shim relocation (#9251) relies
on was documented only in a comment at the top of
src/deprecated/deprecated.js.

- Correct the build system, Node version and polyfill statements
- Describe what build.mjs emits, how the .d.ts is produced and what is
  stripped from non-debug builds
- Record the sideEffects: false rules: no module-scope side effects,
  deprecated aliases in src/deprecated/deprecated.js, prototype shims at
  the bottom of the owning module, guarded by test/bundles/treeshake.test.mjs
- List src/deprecated/, the bundle tests and the remaining Debug methods

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants