Repository navigation
fix(core): bundling a project no longer blocks the host's thread on esbuild - #5714
Conversation
Edit accuracy: accurate 271 (base branch 271), smooth 144 of thoseThe gate passes. Quarantined, measured but not gated (0) |
terencecho
left a comment
There was a problem hiding this comment.
Source-only review at c093a4bf8f9bad0a8fd5597ba333a19902b3114f, against effective base d05bc4215d5757da86956217f4a8a4b2ab11b1fd.
packages/core/src/compiler/htmlBundler.ts:828–857: the async transform stays inside the existing fallback boundary, retaining transform options, provenance construction and escaping after resolution.packages/core/src/compiler/htmlBundler.ts:736–767,1365–1384: every private-helper consumer awaits its result; sequential script/anchor placement and completion before font deferral/serialization are preserved. The public API remainsPromise<string>.packages/core/src/compiler/htmlBundler.esbuildAsync.test.ts:10–38: the sync-API guards record before throwing, so fallback cannot conceal a forbidden call; output assertions also require real comment removal and preserved code.
Audited: both changed files in full, existing BASE before HEAD; complete private-helper call census; relevant script-run/escaping helpers and bounded CLI/Studio/Inspector integration evidence. Two independent source-only audits found no introduced reachable blocker. No existing blocking review or exact-head approval was present in the reviewed public record.
Not verified: test/typecheck execution, native responsiveness/profile claims, or universal byte-for-byte esbuild output parity. This is not a whole-repository semantic audit.
Verdict: APPROVE
Reasoning: The async migration propagates through every changed helper consumer without a demonstrated ordering, error-fallback, provenance or served-output regression.
— tai
What
Bundling a project (
bundleToSingleHtml) no longer blocks the host's thread on esbuild. Script comment stripping used esbuild'stransformSync, which holds the calling thread until esbuild answers. A host that bundles on its main thread (a desktop app re-bundling after every edit) stalled on each script. It now uses esbuild's asynctransform, which leaves the thread free while esbuild works.No public API changes:
bundleToSingleHtmlwas already async, and every call site of the comment stripper sits inside the asyncbundleProject. The output is the same, since the same esbuild transform runs with the same options.Why this fix
I considered three options:
Verification
New
htmlBundler.esbuildAsync.test.ts: esbuild's sync APIs are mocked to throw and record the call, and the async ones stay real. Bundling a project whose scripts carry block and line comments must strip both and make no sync call. On main it fails withexpected [ 'transformSync' ] to deeply equal [].All
packages/core/src/compilertests green 3 runs in a row (562 tests). Both core typechecks (tscandtsc -p tsconfig.runtime.json) are clean, as are oxlint and oxfmt.Desktop main-process before/after: a desktop app that bundles on its main process after each agent write, profiled over a ~140 s agent run on a Linux box. Both sides use a locally packed core, built from main and from this branch, and run twice each, alternating:
runCallSync)Before, the heaviest sync chain was
transformSync←stripJsCommentsParserSafe←bundleProject. After, no esbuild call appears on the main thread. The remaining bundling work there is about 150 ms per run.