Repository navigation
[builders] Compile JSX in steps bundles loaded directly at runtime - #5304
joelfickson wants to merge 3 commits into
Conversation
Signed-off-by: Joel Fickson <joel.fickson@vercel.com>
🦋 Changeset detectedLatest commit: 439309e The changes in this PR will be included in the next version bump. This PR includes changesets to release 17 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
📊 Workflow Benchmarkscommit Backend:
📈 STSO distribution vs main (inline / queue-hop histograms)1020 steps (inline) Cumulative STSO time: main 98830ms → this run 98457ms (Δ -373ms, 0%) 📜 Previous results (1)f4f0bb4Sat, 07 Nov 2026 16:13:07 GMT · run logs
ℹ️ Metric definitions & methodologyThe collapsed STSO distribution section above buckets every step gap, split inline (same warm process — pure framework overhead) vs queue-hop (fresh process — dispatch, reinit, replay). Best/P75/P90/P99 deltas compare against the most recent benchmark run on Metrics — TTFS: time to first step body (in-deployment start() → first step body) · Fan-out TTFS: fan-out time to first step (in-deployment start() → first of the parallel step bodies to complete) · Fan-out TTLS: fan-out time to last step (in-deployment start() → last of the parallel step bodies to complete, i.e. when the Promise.all resolves) · STSO: step-to-step overhead (gap between consecutive step bodies) · WO: workflow overhead (whole-run time outside step bodies, in-deployment anchored) Scenarios — step: one trivial no-op step, no stream; no hooks, so the run stays in turbo mode (in-process fast path) · stream: one streaming step; no hooks, so the run stays in turbo mode (in-process fast path) · hook + stream: registers a hook before one step, which exits turbo mode (dispatch path) · 1020 steps: 1020 trivial sequential steps; STSO is measured between consecutive steps in the given step ranges, and WO is the whole-run overhead outside step bodies · Promise.all(100 steps): 100 trivial no-op steps started together in a single Promise.all; Fan-out TTFS is the first of them to complete and Fan-out TTLS the last, both from the in-deployment clientStart, so their gap is the spread the runtime adds across the fan-out 🔴 marks a percentile over its target (within target is left unmarked). Targets (p75/p90/p99, ms) — TTFS 200/300/600 All timestamps are deployment-side; runs are triggered in-deployment, so the CI runner and api.vercel.com sit outside every measured window. TTFS = Cold starts stay in the numbers (real bursty-workload latency, inflates P75+); Best is the warm floor. |
🧪 E2E Test Results✅ All tests passed 🛠 Infra Events (absorbed by the harness)Platform anomalies the e2e harness detected and worked around (e.g. a run the queue never picked up, replaced by a fresh run). Clustered timestamps indicate a backend blip; a steady drip indicates a platform issue worth escalating.
E2E Test SummarySummary
Details by Category✅ ▲ Vercel Production
✅ 💻 Local Development
✅ 📦 Local Production
✅ 🐘 Local Postgres
✅ 🪟 Windows
✅ 🌐 Cross-language Conformance
✅ dynamic-runs
✅ local-postgres-spec9
✅ vercel-http-transport
✅ vercel-multi-region
✅ vercel-spec9
✅ vercel-ws-transport
|
Sim WorldSimulated world deterministic testing for races. Traces 🟢 world-sim scenario book — 0 fail of 45 total
Full trace: |
About these numbersSizes are gzip; parentheses show the change against
|
Signed-off-by: Joel Fickson <joel.fickson@vercel.com>
Signed-off-by: Joel Fickson <joel.fickson@vercel.com>
Description
When
bundleTransitiveLocalStepDependenciesis on (Nitro dev, Vitest, NestJS ESM), project-local files are inlined into a steps bundle that is loaded straight from disk, but the bundle keptjsx: 'preserve'. A step that imports a.tsxmodule failed withUnexpected token '<'. These bundles now compile JSX with esbuild's automatic runtime, which still honors the tsconfig'sjsxImportSource. Bundles handed to another bundler keeppreserve, so production output is unchanged.A classic runtime (
"jsx": "react"withjsxFactory) is not fixed by this: the SWC pass that runs before esbuild removes the factory binding, so those projects now fail withReferenceErrorinstead of a syntax error.Closes #5286
How did you test your changes?
New
steps-bundle-jsx.test.tsbuilds a steps bundle where a step imports a.tsxfile, imports it in a fresh Node process and runs the step, once with a stubreactJSX runtime and once with a stubpreactruntime set throughjsxImportSource, plus a control that checks JSX stays preserved when the flag is off. The full@workflow/builderssuite passes. A Nitro dev app on workflow 5.4.0 with a packed build of this branch went from a run stuck inpendingtocompleted, andnitro buildstill succeeds.PR Checklist - Required to merge
pnpm changesetwas run to create a changelog for this PRgit commit --signoffon your commits)