Skip to content

build: migrate js builds to esbuild#8722

Merged
kpal81xd merged 15 commits into
mainfrom
build/esbuild-engine-build
May 15, 2026
Merged

build: migrate js builds to esbuild#8722
kpal81xd merged 15 commits into
mainfrom
build/esbuild-engine-build

Conversation

@kpal81xd
Copy link
Copy Markdown
Contributor

@kpal81xd kpal81xd commented May 12, 2026

Description

Migrate the engine JavaScript build targets from Rollup to esbuild for faster clean and watch builds.

  • Adds esbuild target helpers and transform plugins for JSCC preprocessing, debug stripping, shader chunk
    processing, dynamic import handling, and import validation.
  • Routes JS build and watch targets through esbuild, requires explicit JS type/format for direct build.mjs
    leaf commands, and uses Turbo for aggregate build/watch orchestration.
  • Speeds type declaration generation by invoking TypeScript and Rollup APIs directly.
  • Preserves Rollup-style build logging, including watch rebuild start and completion logs.
  • Moves build:treemap, build:treenet, and build:treesun to esbuild metafiles via
    esbuild-visualizer; drops build:treeflame because there is no esbuild-compatible flamegraph
    template.

Build comparison

Deltas compare current PR head 2f80a12a2 against origin/main 6df566a37 in isolated worktrees. Build speed is
a clean one-shot target build; watch build speed is the watcher rebuild after a content touch to src/core/guid.js.
JS artifact sizes were measured from target outputs before type generation is mixed into ESM tree totals.

This table uses ~same for negligible changes: timing deltas under 10%, and size deltas that are byte-identical
or round below 0.1 KiB.

Artifact / Target Raw size Δ Gzip size Δ Build speed Watch rebuild speed
rel UMD -21.5 KiB (-0.6%) +27.1 KiB (+3.7%) 5.9× faster 4.7× faster
rel ESM bundle+tree -339.7 KiB (-4.5%) +18.3 KiB (+1.0%) 2.5× faster 5.1× faster
dbg UMD -3424.5 KiB (-15.2%) -1054.5 KiB (-20.3%) 11.1× faster 8.1× faster
dbg ESM bundle+tree -4698.2 KiB (-16.1%) -1296.4 KiB (-18.6%) 3.4× faster 14.3× faster
prf UMD -21.7 KiB (-0.6%) +27.1 KiB (+3.7%) 6.4× faster 5.1× faster
prf ESM bundle+tree -341.2 KiB (-4.5%) +18.0 KiB (+1.0%) 2.5× faster 6.3× faster
min UMD +51.9 KiB (+2.3%) +23.3 KiB (+4.1%) 8.2× faster 7.4× faster
min ESM +43.2 KiB (+1.9%) +21.3 KiB (+3.7%) 7.7× faster 6.4× faster
types ~same ~same 1.1× faster 2.9× faster
total / summed targets -8751.6 KiB (-10.4%) -2215.9 KiB (-11.3%) 2.7× faster 5.1× faster

Notes

  • Public API changes: none.
  • Public package entry fields are unchanged: type, main, module, and exports.
  • JS export names, export typeof shapes, and primitive exported constants match for UMD, bundled ESM,
    unbundled ESM, and minified outputs. The only ignored primitive is revision, which is commit-specific.
  • Type declaration export names match. Textual declaration differences are limited to generated ordering/details
    that do not change the public export surface.
  • ESM tree output structure differs internally: fflate now uses a stable modules/fflate/... path instead of
    Rollup's symlink-derived absolute path, and esbuild emits src/extras/index.js. Neither changes public exports.
  • Release/profile ESM output preserves native public class fields to avoid repeated esbuild helper output. This is
    the main compatibility consideration for ESM consumers.
  • Debug size reductions come from smaller generated JS and a smaller inline sourcemap; debug code is not stripped,
    and dbg does not use the indentation compaction pass. The sourcemap savings are mainly fewer names entries
    and shorter mappings.
  • Tree visualizer scripts now use esbuild metafiles and esbuild-visualizer for build:treemap,
    build:treenet, and build:treesun. build:treeflame was removed because the esbuild visualizer
    has no flamegraph template.
  • Rollup remains in use for examples and declaration bundling.

Manual validation

  • Compared output sizes and clean/watch build timings for release, debug, profile, minified, and type targets.
  • Compared package public entry fields, JS export names/types/primitive constants, and declaration export names.
  • Smoke-loaded UMD, bundled ESM, unbundled ESM, and minified outputs.
  • Checked rel ESM --sourcemaps output on both branches and confirmed matching exports.
  • Ran npm run publint and npm run test:types.
  • Checked direct build.mjs CLI validation for explicit JS target flags and aggregate watch guidance.
  • Checked esbuild-backed treemap, treenet, and treesun visualizer scripts, including a watch rebuild smoke test.

Checklist

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

@Maksims
Copy link
Copy Markdown
Collaborator

Maksims commented May 12, 2026

What are build size changes in terms of %?

@kpal81xd
Copy link
Copy Markdown
Contributor Author

What are build size changes in terms of %?

Adding them - this is only provisional. Gonna try to see if i can squeeze more performance against size gains out before I take the PR out of draft

@kpal81xd
Copy link
Copy Markdown
Contributor Author

kpal81xd commented May 12, 2026

Build comparison for the latest optimization commit against the previous esbuild migration commit.

Compared f39ba765b (build: optimize esbuild module builds) against 3d622116a (build: migrate js builds to esbuild). Build speed is a clean one-shot target build; watch build speed is the watcher rebuild after a temporary src/index.js source change.

Measurements are noisy, so this table uses ~same when a delta is not meaningful. For timing, that means either a delta under 10%, or a bundled/type target with byte-identical output where this optimization commit did not change that target's build path. For size, that means byte-identical output or a delta that rounds below 0.1 KiB.

Artifact / Target Raw size Δ Gzip size Δ Build speed Watch build speed
rel UMD ~same ~same ~same ~same
rel ESM bundle+tree -107.1 KiB (-1.3%) -25.4 KiB (-1.3%) ~same 2.8× faster
dbg UMD ~same ~same ~same ~same
dbg ESM bundle+tree -13326.3 KiB (-35.2%) -4062.1 KiB (-41.8%) ~same 1.5× faster
prf UMD ~same ~same ~same ~same
prf ESM bundle+tree -107.1 KiB (-1.3%) -25.4 KiB (-1.3%) 1.2× slower 2.0× faster
min UMD ~same ~same ~same ~same
min ESM ~same ~same ~same ~same

@kpal81xd
Copy link
Copy Markdown
Contributor Author

Additional type generation comparison for the current type-build optimization work.

Compared baseline commit f39ba765b (build: optimize esbuild module builds) against the current working tree on build/esbuild-engine-build with the type-build changes applied. These type-build changes are not committed yet, so there is not a new commit hash for the optimized side at the time of this measurement.

Build speed is a clean one-shot node build.mjs --type=types; watch build speed is the type watcher rebuild after a temporary src/index.js source change.

Artifact / Target Raw size Δ Gzip size Δ Build speed Watch build speed
types ~same ~same 1.1× faster 2.9× faster

Measured values:

Metric Baseline Optimized
Raw size 2,206,755 bytes 2,206,755 bytes
Gzip size 436,401 bytes 436,396 bytes
Clean build 6.8s 6.1s
Watch rebuild 6.3s 2.2s

The generated playcanvas.d.ts API is semantically unchanged. The textual diff is limited to TypeScript reordering union members in a few declarations, for example Texture.encoding, platform.environment, platform.browserName, and some internal WebGL numeric unions. There are no added or removed declarations.

@kpal81xd kpal81xd added the enhancement Request for a new feature label May 12, 2026
@kpal81xd kpal81xd marked this pull request as ready for review May 13, 2026 11:50
@kpal81xd kpal81xd requested a review from a team May 13, 2026 11:51
@kpal81xd kpal81xd force-pushed the build/esbuild-engine-build branch from 4ded5bd to cffffc8 Compare May 13, 2026 12:24
@kpal81xd kpal81xd force-pushed the build/esbuild-engine-build branch from cffffc8 to 8b3495a Compare May 13, 2026 14:42
@kpal81xd kpal81xd requested a review from mvaligursky May 14, 2026 10:23
@kpal81xd kpal81xd merged commit 52d29d0 into main May 15, 2026
8 checks passed
@kpal81xd kpal81xd deleted the build/esbuild-engine-build branch May 15, 2026 12:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement Request for a new feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants