Skip to content

test(router-plugin): implementation-agnostic code-splitting tests and the compiler test harness - #8906

Open
Sheraff wants to merge 18 commits into
mainfrom
test/compiler-harness-splitting
Open

Sheraff wants to merge 18 commits into
mainfrom
test/compiler-harness-splitting

Conversation

@Sheraff

@Sheraff Sheraff commented Nov 8, 2026 •

Copy link
Copy Markdown
Collaborator

First slice of #8817's test suite, landing on main before the compiler swap. Tests only: no published code changes.

The harness

packages/compiler-test-utils (private) is the test harness of #8817's suite. Tests use it to drive the router plugin the way an app does:

  • real Vite, Rsbuild, Rspack and webpack builds and dev servers on temporary apps;
  • route apps rendered in pages of a real Chromium;
  • one channel that collects every warning and error, checked by severity, file and position.

The tests go through the public plugins and options only. They check what a user sees (what renders, what loads lazily, what a build reports), never the compiler's output text. Any correct compiler should pass them, Babel-based or not.

Only the parts this slice uses come along. These are left out: global-trap, rsbuild-plugin-host, workspace-packages, native-import.cjs, TSR_COMPILER_VERIFY, unused exports (most of hmr-sync and determinism), and the harness self-tests of those modules. oracle/KNOWN-BUGS.md keeps only the upstream issues the harness code cites. The pins list comes with the swap. @tanstack/compiler-vite-versions holds Vite 6 and 7 for vite-versions.test.ts.

What the slice covers

#8817's route code splitting tests (router-plugin, area rules of the split plan), re-run on current main with this harness, every test twice:

result on main tests
pass 1,029
fail (in both runs) 587
.fails pin in #8817 20 (1 passes on main)
tests the new compiler's internals 2

No test gave different results in the two runs. 21 tests that failed on Nov 3 pass now, after this week's fixes on main.

This PR first brought 1,012 of the passing tests; after the re-syncs with #8817 and the review fixes below it carries 1,090:

18 passing tests stay out, because they share a table cell with failing ones. Cutting them would need a per-bundler condition in the test, so they come with the fix.

Only tests that pass on main

There are no new .fails pins and no skipped tests. A test that fails on main comes with the PR that fixes it.

CI wiring

  • router-plugin test:unit is the fast tier. It runs in process, with client checks in Chromium pages.
  • router-plugin test:integration is the slow tier: real builds, Rsbuild dev servers, child Node runs and browsers. It runs two Vitest projects, integration and integration-pages.
  • As in refactor(compiler)!: replace Babel with a Yuku-based compiler core for Router and Start #8817, Nx runs test:integration as four shard targets, test:integration--shard-<i>-of-4 (Vitest --shard). They run one after another on a machine, are spread over CI's agents, and each is cached on its own. test:integration:whole runs the tier in one Vitest run, for file filters and budget measurements.
  • These are wired as refactor(compiler)!: replace Babel with a Yuku-based compiler core for Router and Start #8817 wires them: a test:integration target default in nx.json (and test:unit ignores tests/integration/**), parallelism: false, and at most 4 workers. pnpm test:pr already runs test:integration.
  • compiler-test-utils has its own test:unit and test:integration (the harness self-tests).
  • The Compiler Platforms workflow now installs Chromium (Playwright's, or Alpine's in the musl container), because router-plugin's test:unit opens pages.
  • The css-modules e2e apps take refactor(compiler)!: replace Babel with a Yuku-based compiler core for Router and Start #8817's sass bump (^1.105.1). Otherwise pnpm resolves two copies of vite and vitest for the harness and the plugins.
    • The bump changes no CSS: these apps' SCSS compiles to byte-identical CSS with 1.97.2 and 1.105.1. A one-off failure of the Vue app's dev e2e at ad808b6 (an element read while detached, "", on a plain-CSS element) passed 3/3 locally on this branch and on main, and 40/40 under load, so I re-ran it.

Main's tests that stay run in their own unit-main project, as they always did: sequential, and with the generator's temporary files in the package. These are:

  • route HMR: add-hmr, handle-route-update, react-refresh-route-components, router-plugin-context, and the Solid/Vue and webpack HMR tests of code-splitter-plugin-pipeline;
  • the error for a split module id without a split value;
  • config;
  • the kept part of the snapshot test;
  • the kept case of production-warnings (see below).

What's deleted, and coverage

Deleted: main's Babel-specific splitting tests that the new ones replace.

Coverage was measured with V8 line and branch coverage, on the same denominators, over router-plugin's tests. Main's suite today is compared with the suite after this PR:

file lines main → after branch arms main → after
core/code-splitter/compilers.ts 539 → 546 / 564 242 → 252 / 269
core/router-code-splitter-plugin.ts 99 → 105 / 115 36 → 40 / 53
core/code-splitter/framework-options.ts 6 → 8 / 9 2 → 3 / 4
core/code-splitter/plugins/* equal equal
core/router-generator-plugin.ts 35 → 53 / 60 5 → 10 / 14
core/utils.ts 16 → 17 / 18 7 → 8 / 9

No file covers less. To get there, two of main's tests stay, because the new suite doesn't reach their code yet:

  • code-splitter.test.ts, cut down to the 4 inputs that cover it:

    • using.tsx: the one-call createFileRoute({ … }) form;
    • boolean-null-literals.tsx;
    • retain-exports-destructured.tsx: export const { a } = …;
    • destructured-export-multiple.tsx.

    The cut file also keeps the Solid input, and the React Refresh lowercase-rename test (HMR).

  • detect-route-codesplit-groupings.test.ts: groupings read from the one-call form.

Lines only main's suite still reaches: compilers.ts:51 (removeBindingsDependingOnRoute, which only tests call), and router-code-splitter-plugin.ts:224 (the error for a split module id without a split value), which the kept code-splitter-plugin-pipeline test covers.

CI cost

Measured locally: Nx, dependencies already built, 4 workers, 3 runs. Peak memory is the summed PSS of the process tree, Chromium included.

target wall peak memory tests
router-plugin test:unit (main today) 9.2 s 3.2 GB 913
router-plugin test:unit (this PR) 13.7 s 5.4 GB 243
router-plugin test:integration (new), as 4 shards in sequence 80.5 s 7.2–7.3 GB 997 (211 + 449 + 164 + 173)
router-plugin test:integration:whole (one Vitest run) about 60 s – 997
compiler-test-utils test:unit (new) 8 s 1.0 GB 70
compiler-test-utils test:integration (new) 12.6 s 2.1 GB 101

That is about 115 s of test time on one machine, against 9 s today. On CI the shards run on separate agents. Before sharding, CI took 3 m 58 s for router-plugin test:integration on one agent.

CI on this PR: main's build was broken (fixed by #8907)

Before #8907, main itself didn't build. These jobs fail on start-plugin-core:build with src/rsbuild/virtual-modules.ts:602: TS2552: Cannot find name 'paths':

  • Benchmark PR, and the six SSR and memory-server CodSpeed jobs;
  • Preview;
  • every Compiler Platforms job.

The client-side benchmarks pass because they don't build Start. Main's own Bundle Size, Benchmarks and Release runs on c156097786 fail with the same error.

The cause is two of today's Start PRs crossing:

pathsOf().manifest at that line makes the build pass locally. The fix belongs on main, not in this tests-only PR.

On every Compiler Platforms job (Windows x64, macOS arm64, Linux arm64, Linux x64 musl), the steps this PR adds pass: Chromium installs, and router-plugin's test:unit passes (234/234 on 33bf9b5). The failure is the later "Production builds" step, which builds Start.

Bundle Size: Rsbuild module ids only, no code change

The Bundle Size job reports +6 B raw (+8 to +12 B gzip) for react-start.rsbuild.{minimal,minimal-iife,full}; the Vite scenarios are unchanged. No built code changes. Only Rspack's module and chunk ids move:

  • No package version moves. The lockfile only adds packages (yuku, the Vite 6/7 aliases, Babel/Solid test plugins), and replaces sass 1.97.2 with 1.105.1 in the css-modules e2e apps.
  • But install directory names change. The sass bump changes the peer variant of vite, so every package with vite in its peer chain gets a new .pnpm directory name. unplugin 3.7.0, which provides the router plugin's Rspack loader, moves from unplugin@3.7.0_…_f1bc3eee… to unplugin@3.7.0_…_e5f03c08….
  • Rspack hashes those paths into its ids. Its deterministic module ids hash each module's request, loader paths included, so the ids change. Vite's ids don't include loader paths.
  • Checked locally on main 70bbd11025 and this branch:
    • both builds bundle the same 102 source files (the source maps' sources are identical);
    • all six emitted chunks are identical once module and chunk ids are masked;
    • the whole raw difference is ids: for example, the async chunk is 9 on main and "w" here (+2 B per use).

#8817 takes the same sass bump, so it will show the same shift.

Re-sync with #8817 5bd66855c3

Applied from #8817 since 294b3f36e1:

  • the integration shards: router-plugin targets and the nx.json defaults;
  • per-file run pages and browser context (browser.ts, test-scope.ts, test-scope-setup.ts);
  • SPEC.md and the harness notes.

Not applied:

  • hmr-sync.ts's new errorsOutsideReloads, used only by Start's route-edit tests;
  • the new code-splitter-effect-timing tests (6) and the changed code-splitter-kept-reports (4), which fail on main in both runs.

#8817 removed or renamed no test in this slice.

Re-sync with #8817 ac17b427d3

Main is merged in (e7358c36d8: pnpm 12, the RSC bump). The lockfile is main's, regenerated with pnpm 12. pnpm 12 merges a version a package names directly into other packages' ranges, so two ranges differ from #8817's to leave every other package resolving as on main: the harness's esbuild (^0.28.1) and router-plugin's @babel/preset-typescript (7.27.1). Outside the slice's packages, only the css-modules apps' sass bump changes.

Applied from #8817 since 5bd66855c3:

  • harness fixes: a pin passes only on an assertion error; an edit without its outcome fails as an assertion; child Node runs report their step and time out at 25 s; webpack/Rspack watch rebuilds wait for the build that saw the edit; binary app files; map helpers; the pins and run-directory controls;
  • the integrationProject refactor of router-plugin's Vitest config;
  • new code-splitting tests that pass on main: build-map-sources, build-js-extension-assets, code-splitter-other-names, -pure-framework-calls (Vue, Solid), -unreadable-loader, -value-own-writes, -const-chains, -effect-timing (decorators), vite-unanalysed-modules, 14 new shapes of code-splitter-state-read-at-load, one effectful-declaration row.

Not applied:

Mirrored: #8817 deletes code-splitter-reexported-factory.test.ts. Main passed it only by accident: its compile crashes on a duplicate createFileRoute import, and the crash's code frame contains the expected text.

Review fixes (independent review, 2026-11-12)

Each item was checked on this branch first, then fixed:

item fix commit
S1 router-plugin AGENTS.md pointed at the deleted snapshot suite describes the two test tiers, loadRoute/build, targetFramework and the unit-main project 301cbd8896
S2 esbuild's refusal was no longer asserted with its message esbuild.test.ts asserts main's error text for autoCodeSplitting: true; the build test's "Bug:" comment says refusing is valid 76f0a4d38e
S3 main's Solid/Vue route HMR check was deleted kept from code-splitter-plugin-pipeline.test.ts (Vite HMR handling appended, route unchanged) 7083a064ff
S4 the malformed split id error lost its test kept: a split module id without a split value reports The split value for the virtual route… 7083a064ff
S5 harness docs described #8817's state KNOWN-BUGS.md drops the 9 rows nothing here cites; the harness AGENTS.md and the known-bugs headers say what holds on main c035cbc3f2
S6 unused code removed TSR_COMPILER_VERIFY and its self-test, the harness's Nx dependency on @tanstack/history, other packages' budgets, hmr-sync except trackRequests, and determinism's reordering helpers with their self-tests. describeHmr stays: the dev-server self-tests use it c051f66f56
S7 openPage leaked its slot and context when a page failed to open; runInBrowser could wait forever a page that fails to open is closed, which frees its slot; a client run's load and script race a timeout (25 s by default). Two self-tests time out before the fix and pass after it 52f98bdf02
S8 code-splitter-extracted-export-chunking mixed cases and read an internal query the function case only: the exported function stays lazy (the chunk carries its copy), and nothing is reported for the route file 32cc29c26b
S9 the two "is reported nothing" tests of route-unrecognized-fixes file removed b326834dc0
N1 headers of cut files described missing tests; N2 a title that overclaimed; N3 references to design documents main doesn't have trimmed and retitled; references removed from the test files (SPEC.md is unchanged, as #8817 has it) ad808b62a9
N5 brace-less if in page-side strings of route-app.ts braces added 34f9d75283
N7 the free-name judge parses with Yuku one paragraph in oracle/README.md 15a5c9bc7a

Not changed:

F4: which branch the either-or tests take on main. I logged each test's branch with temporary instrumentation (not committed):

  • imported-options: the route works;
  • route-redeclared: refused with an error on Vite and Rspack;
  • esbuild: refused, now also asserted by its message;
  • errorComponent shapes: 4 lazy, 1 reported;
  • factory routes: all 5 lazy; the repeated factory: both split;
  • pragmas: React and Solid refuse, naming both plugins; Vue builds, lazy;
  • exported-imported HMR: not split, warns;
  • production-warnings: not split, warns, on Rspack and webpack.

Each test still asserts something useful on main. A refusal must be a build error that names the cause, never a broken page or a silent unsplit build.

For #8817: take the S7 fix and its self-tests (52f98bdf02: src/browser.ts, src/build-harness.ts and two harness self-tests; it applies to #8817's copies of those files), and retitle "a namespace of types only stays out of every chunk" there too. Everything else conflicts on paths #8817 already owns, and resolves to its side or to deletion as before.

Validation at ad808b62a9 (main e7358c36d8, no newer commit):

  • test:unit, test:types and test:eslint for router-plugin, router-utils and compiler-test-utils: 18/18.
  • Integration, 3 times:
    • router-plugin: 997/997 as 4 shards (211 + 449 + 164 + 173), 80.2–80.5 s, 7.2–7.3 GB peak;
    • compiler-test-utils: 101/101, 12.5–12.6 s, 2.1 GB peak.
  • start-plugin-core:build passes.
  • Unit tests: router-plugin 243, compiler-test-utils 70.

Relation to #8817

I merged this branch into main locally, then test-merged #8817's head (ac17b427d3) on top. That gives 74 conflicts, and each one resolves to #8817's side:

With every conflict taken from #8817's side, the merged tree equals #8817's head except for main's commits #8817 hasn't merged yet (#8907, #8912, #8913, #8919) and the autofix bot's labeler-config.yml entries. Nothing from the slice differs.

Still open for #8817: a webpack or Rspack production build without mode of a route that exports a component ships no splitter warning (kept here as production-warnings.test.ts). #8817's no-mode rows (build-production*.test.ts) compare against a no-mode control on a route without exports. The map-name gap is closed: build-map-sources covers it.

🤖 Generated with Claude Code

… the compiler test harness

Adds `@tanstack/compiler-test-utils`, the harness of #8817's compiler test
suite: real Vite, Rsbuild, Rspack and webpack builds and dev servers, route
apps in pages of a real Chromium, and one merged diagnostic channel. Only the
parts the route code splitting tests use come along.

Adds #8817's route code splitting tests that pass on main's compilers: whole
files where every test passes, and the passing describe groups and table
rows of mixed files. Its one pin that main passes (Rolldown, a `var`
declared again in a head or a pattern) lands as an ordinary test. The slow
tier runs as router-plugin `test:integration`.

Deletes main's Babel-specific splitting tests the new ones replace: the
code-splitter snapshot matrix (except the four fixtures that cover shapes
the new tests do not reach yet), shared-bindings-helpers, utils,
delete-nodes, the old regression suites, production-warnings and
source-maps. Main's route HMR tests stay, in their own `unit-babel`
project, until the route HMR slice replaces them.

Takes #8817's sass bump of the css-modules e2e apps, so that the harness and
the plugins load one copy of vite and vitest.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Sheraff
Sheraff requested a review from a team as a code owner November 8, 2026 16:14
@changeset-bot

changeset-bot Bot commented Nov 8, 2026 •

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: ad808b6

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai

coderabbitai Bot commented Nov 8, 2026

Copy link
Copy Markdown
Contributor

Walkthrough

Warning

Review details and warnings were omitted to fit the comment limit.

@nx-cloud

nx-cloud Bot commented Nov 8, 2026 •

Copy link
Copy Markdown
Contributor

View your CI Pipeline Execution ↗ for commit ad808b6

Command Status Duration Result
nx affected --targets=test:eslint,test:unit,tes... ✅ Succeeded 9m 31s View ↗

💡 With Ultracache enabled, Nx Cloud learns each task's file inputs in CI and uses them on later runs. Turn on Ultracache in workspace settings ↗ · Read docs ↗


☁️ Nx Cloud last updated this comment at 2026-11-12 17:24:27 UTC

@socket-security

socket-security Bot commented Nov 8, 2026 •

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Added@​rsbuild/​plugin-solid@​1.2.2861007495100
Addedvite@​7.3.8981008298100
Addedvite@​6.4.6911008298100
Addedyuku@​0.27.0981009295100

View full report

@socket-security

socket-security Bot commented Nov 8, 2026 •

Copy link
Copy Markdown

Warning

Review the following alerts detected in dependencies.

According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.

Priority Alert  (click "▶" to expand/collapse) Action
Low priority
Low adoption: npm @yuku-toolchain/darwin-arm64

Location: Package overview

From: packages/compiler-test-utils/package.json → npm/yuku@0.27.0 → npm/@yuku-toolchain/darwin-arm64@0.27.0

ℹ Read more on: This package | This alert | What are unpopular packages?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Unpopular packages may have less maintenance and contain other problems.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/@yuku-toolchain/darwin-arm64@0.27.0. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn
Low priority
Low adoption: npm @yuku-toolchain/darwin-x64

Location: Package overview

From: packages/compiler-test-utils/package.json → npm/yuku@0.27.0 → npm/@yuku-toolchain/darwin-x64@0.27.0

ℹ Read more on: This package | This alert | What are unpopular packages?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Unpopular packages may have less maintenance and contain other problems.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/@yuku-toolchain/darwin-x64@0.27.0. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn
Low priority
Low adoption: npm @yuku-toolchain/linux-arm64

Location: Package overview

From: packages/compiler-test-utils/package.json → npm/yuku@0.27.0 → npm/@yuku-toolchain/linux-arm64@0.27.0

ℹ Read more on: This package | This alert | What are unpopular packages?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Unpopular packages may have less maintenance and contain other problems.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/@yuku-toolchain/linux-arm64@0.27.0. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn
Low priority
Low adoption: npm @yuku-toolchain/win32-arm64

Location: Package overview

From: packages/compiler-test-utils/package.json → npm/yuku@0.27.0 → npm/@yuku-toolchain/win32-arm64@0.27.0

ℹ Read more on: This package | This alert | What are unpopular packages?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Unpopular packages may have less maintenance and contain other problems.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/@yuku-toolchain/win32-arm64@0.27.0. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn
Low priority
Low adoption: npm @yuku-toolchain/win32-x64

Location: Package overview

From: packages/compiler-test-utils/package.json → npm/yuku@0.27.0 → npm/@yuku-toolchain/win32-x64@0.27.0

ℹ Read more on: This package | This alert | What are unpopular packages?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Unpopular packages may have less maintenance and contain other problems.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/@yuku-toolchain/win32-x64@0.27.0. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn

View full report

@github-actions

github-actions Bot commented Nov 8, 2026 •

Copy link
Copy Markdown
Contributor

🚀 Changeset Version Preview

2 package(s) bumped directly, 3 bumped as dependents.

🟨 Minor bumps

Package Version Reason
@tanstack/start-plugin-core 1.171.57 → 1.172.0 Changeset

🟩 Patch bumps

Package Version Reason
@tanstack/react-start-rsc 0.1.67 → 0.1.68 Changeset
@tanstack/react-start 1.169.6 → 1.169.7 Dependent
@tanstack/solid-start 1.169.6 → 1.169.7 Dependent
@tanstack/vue-start 1.169.6 → 1.169.7 Dependent

… map-name checks

The slice has no test for two behaviours main guards: a webpack or Rspack
production build whose configuration has no `mode` ships no splitter
warning (#8269), and on webpack and Rspack the maps of a split component
and of shared code name the route file, not the `?tsr-split` id (#8860).
Keep those cases of main's tests, cut to what the slice does not cover:
the `mode: 'production'` rows, the line mapping and Vite's dev server are
asserted in the integration tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@codspeed

codspeed Bot commented Nov 8, 2026 •

Copy link
Copy Markdown

Merging this PR will improve performance by 7.53%

2 warnings

⚠️ 61 benchmarks are dominated by system calls

System calls cannot be simulated consistently and are left out of the measure. The reported value understates the real cost. Switch to the Walltime instrument to measure them.

Learn more about system calls

See affected benchmarks

⚠️ 3 benchmarks with a significant change ran on different hardware

Their base and head results were measured on machines with a different CPU, core count or memory, so the changes might not come from the code. Run base and head on the same runner type.

Learn more about Macro Runners

See affected benchmarks

⚡ 3 improved benchmarks
✅ 191 untouched benchmarks
⏩ 3 skipped benchmarks1

Performance Changes

Mode Benchmark BASE HEAD Efficiency
⚡ Memory mem client navigation-churn (solid) 119.1 KB 101.9 KB +16.91%
⚡ Memory mem client interrupted-navigations (solid) 86.4 KB 83.7 KB +3.23%
⚡ Memory mem client unique-location-churn (react) 79 KB 76.7 KB +3.04%

Tip

Curious why performance improved? Comment @codspeedbot explain why performance improved on this PR, or directly use the CodSpeed MCP with your agent.


Comparing test/compiler-harness-splitting (ad808b6) with main (e7358c3)

Open in CodSpeed

Footnotes

  1. 3 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩

Takes #8907, which restores main's start-plugin-core build.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Nov 8, 2026 •

Copy link
Copy Markdown
Contributor

Bundle Size Benchmarks

  • Commit: b467b04762d9
  • Measured at: 2026-11-12T16:48:28.316Z
  • Baseline source: history:e7358c36d8cd
  • Dashboard: bundle-size history

The following scenarios have bundle-size changes compared with the baseline:

Scenario Current (gzip) Initial (gzip) Raw Brotli Trend
react-start.rsbuild.minimal 96.7 KiB
-3 B
96.5 KiB
-3 B
298.3 KiB
+4 B
83.5 KiB
+66 B
███████▁▁▁▁▁
react-start.rsbuild.minimal-iife 97.1 KiB
-2 B
96.9 KiB
-3 B
299.2 KiB
+4 B
83.7 KiB
-85 B
███████▁▁▁▁▁
react-start.rsbuild.full 100.0 KiB
-5 B
99.8 KiB
-4 B
307.9 KiB
+2 B
86.1 KiB
+34 B
███████▁▁▁▁▁

Current gzip tracks all emitted client JS chunks. Initial gzip tracks only the entry/import graph. Trend sparkline is historical current gzip ending with this PR measurement; lower is better.

@pkg-pr-new

pkg-pr-new Bot commented Nov 8, 2026 •

Copy link
Copy Markdown
More templates

@tanstack/arktype-adapter

npm i https://pkg.pr.new/@tanstack/arktype-adapter@8906

@tanstack/eslint-plugin-router

npm i https://pkg.pr.new/@tanstack/eslint-plugin-router@8906

@tanstack/eslint-plugin-start

npm i https://pkg.pr.new/@tanstack/eslint-plugin-start@8906

@tanstack/history

npm i https://pkg.pr.new/@tanstack/history@8906

@tanstack/react-router

npm i https://pkg.pr.new/@tanstack/react-router@8906

@tanstack/react-router-devtools

npm i https://pkg.pr.new/@tanstack/react-router-devtools@8906

@tanstack/react-router-ssr-query

npm i https://pkg.pr.new/@tanstack/react-router-ssr-query@8906

@tanstack/react-start

npm i https://pkg.pr.new/@tanstack/react-start@8906

@tanstack/react-start-client

npm i https://pkg.pr.new/@tanstack/react-start-client@8906

@tanstack/react-start-rsc

npm i https://pkg.pr.new/@tanstack/react-start-rsc@8906

@tanstack/react-start-server

npm i https://pkg.pr.new/@tanstack/react-start-server@8906

@tanstack/router-cli

npm i https://pkg.pr.new/@tanstack/router-cli@8906

@tanstack/router-core

npm i https://pkg.pr.new/@tanstack/router-core@8906

@tanstack/router-devtools

npm i https://pkg.pr.new/@tanstack/router-devtools@8906

@tanstack/router-devtools-core

npm i https://pkg.pr.new/@tanstack/router-devtools-core@8906

@tanstack/router-generator

npm i https://pkg.pr.new/@tanstack/router-generator@8906

@tanstack/router-plugin

npm i https://pkg.pr.new/@tanstack/router-plugin@8906

@tanstack/router-ssr-query-core

npm i https://pkg.pr.new/@tanstack/router-ssr-query-core@8906

@tanstack/router-utils

npm i https://pkg.pr.new/@tanstack/router-utils@8906

@tanstack/router-vite-plugin

npm i https://pkg.pr.new/@tanstack/router-vite-plugin@8906

@tanstack/solid-router

npm i https://pkg.pr.new/@tanstack/solid-router@8906

@tanstack/solid-router-devtools

npm i https://pkg.pr.new/@tanstack/solid-router-devtools@8906

@tanstack/solid-router-ssr-query

npm i https://pkg.pr.new/@tanstack/solid-router-ssr-query@8906

@tanstack/solid-start

npm i https://pkg.pr.new/@tanstack/solid-start@8906

@tanstack/solid-start-client

npm i https://pkg.pr.new/@tanstack/solid-start-client@8906

@tanstack/solid-start-server

npm i https://pkg.pr.new/@tanstack/solid-start-server@8906

@tanstack/start-client-core

npm i https://pkg.pr.new/@tanstack/start-client-core@8906

@tanstack/start-fn-stubs

npm i https://pkg.pr.new/@tanstack/start-fn-stubs@8906

@tanstack/start-plugin-core

npm i https://pkg.pr.new/@tanstack/start-plugin-core@8906

@tanstack/start-server-core

npm i https://pkg.pr.new/@tanstack/start-server-core@8906

@tanstack/start-static-server-functions

npm i https://pkg.pr.new/@tanstack/start-static-server-functions@8906

@tanstack/start-storage-context

npm i https://pkg.pr.new/@tanstack/start-storage-context@8906

@tanstack/valibot-adapter

npm i https://pkg.pr.new/@tanstack/valibot-adapter@8906

@tanstack/virtual-file-routes

npm i https://pkg.pr.new/@tanstack/virtual-file-routes@8906

@tanstack/vue-router

npm i https://pkg.pr.new/@tanstack/vue-router@8906

@tanstack/vue-router-devtools

npm i https://pkg.pr.new/@tanstack/vue-router-devtools@8906

@tanstack/vue-router-ssr-query

npm i https://pkg.pr.new/@tanstack/vue-router-ssr-query@8906

@tanstack/vue-start

npm i https://pkg.pr.new/@tanstack/vue-start@8906

@tanstack/vue-start-client

npm i https://pkg.pr.new/@tanstack/vue-start-client@8906

@tanstack/vue-start-server

npm i https://pkg.pr.new/@tanstack/vue-start-server@8906

@tanstack/zod-adapter

npm i https://pkg.pr.new/@tanstack/zod-adapter@8906

commit: ad808b6

Sheraff and others added 13 commits November 9, 2026 00:00
…e run pages (#8817 5bd6685)

Takes #8817's test infrastructure changes since 294b3f3 that apply here:

- router-plugin's `test:integration` runs as four Nx shard targets
  (Vitest `--shard`), and `test:integration:whole` runs the tier in one
  Vitest run, for file filters and budget measurements;
- each test file gets its own run pages and browser context, closed when
  the file ends (`onFileFinished` in `test-scope`), so a later file
  inherits none of their memory or cache;
- SPEC and the harness notes, as in #8817.

#8817's new splitting tests (`code-splitter-effect-timing`) and the changed
`code-splitter-kept-reports` fail on main, so they stay out.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Takes main's pnpm 12 upgrade (#8912), the RSC dependency bump (#8919) and
the react-start HMR e2e fix (#8913).

The lockfile is main's, regenerated with pnpm 12 for the slice's packages.
pnpm 12 merges a version a package names directly into the other
packages' ranges, so two ranges of the slice are set to the versions main
already resolves, to leave every other package's resolution as on main:
the harness's `esbuild` (^0.28.1; ^0.28.2 added a second esbuild and moved
webpack's peer variant) and router-plugin's `@babel/preset-typescript`
(7.27.1; ^7.28.5 moved esbuild-plugin-solid's preset and the preset's own
helpers). The only change left outside the slice's packages is the css-modules
e2e apps' sass bump.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Takes #8817's test changes since 5bd6685 that apply on main's
compilers:

- harness: the pin check (a pin passes only on an assertion error), edits
  without their outcome fail as assertions, child Node runs report the
  step they were in and time out below the test timeout, watch rebuilds
  wait for the build that saw the edit, binary app files, map helpers for
  the new map-source test, and its new controls (`pins`, `run-directory`);
- new passing code-splitting tests: `build-map-sources` (it replaces the
  copy of main's webpack/Rspack map-name check), `build-js-extension-assets`,
  `code-splitter-other-names`, `-pure-framework-calls` (Vue, Solid),
  `-unreadable-loader`, `-value-own-writes`, `-const-chains`,
  `-effect-timing` (decorators), `route-unrecognized-fixes`,
  `vite-unanalysed-modules`, 14 new shapes of `code-splitter-state-read-at-load`
  and one effectful-declaration row;
- `code-splitter-reexported-factory` goes as in #8817: main passes it only
  because its compile crashes on a duplicate `createFileRoute`;
- the `integrationProject` refactor of router-plugin's Vitest config.

Left out because they fail on main: #8817's new rows of
`build-source-maps`, `plugin-options` (esbuild), `code-splitter-route-options`
(object loaders with a spread) and the failing rows of the new files. Left
out because they need #8817's core: the compiler stats check of
`test-scope-setup` and its `TSR_COMPILER_STATS` knob.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…shot suite this PR deletes

Review S1. The snapshot guidance and the invariant-suite pointer go with the suite; the two tiers, behaviour tests through loadRoute, no output snapshots and the unit-main project come in. The route HMR bullets stay: main's HMR tests stay.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…with its message again

Review S2. Main's test that tanstackRouter({ autoCodeSplitting: true }) throws comes back in esbuild.test.ts, with main's message. The either-or build test's comment no longer calls the refusal a bug.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…lformed split id error

Review S3 and S4. The ported page test only checks that a Solid or Vue route compiled with HMR stays valid and renders; main's test that the route HMR plugin adds its Vite HMR handling (without code splitting) stays next to the webpack one. Main's test of the error for a split module id without a split value (router-code-splitter-plugin.ts) stays too, with its helper (createCodeSplitterTransforms) back in regression-helpers.ts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review S5. KNOWN-BUGS.md drops the rows that call Babel and unplugin bugs fixed (they are live on main) and the rows whose pins or workarounds sit in test files main does not have. The harness AGENTS.md drops the Start hosts, the integration-alone process and the react-start build, which only the later suites need. The known-bugs test files no longer say each test is a bug today's compiler fixes, nor point at KNOWN-BUGS sections that are not here.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review S6. Removed: the TSR_COMPILER_VERIFY variable (nothing on main reads it) and its self-test; the @tanstack/history build dependency of test:integration; the budgets of packages that do not use the reporter here; settlePage and the hmr-sync scripts with their self-test (the slice uses trackRequests only); reorderings, reorderedRecords and expectDeterministic with their self-tests (the slice uses expectRelocatable only). describeHmr stays: the dev-server harness's own controls use it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nd a client run is bounded

Review S7. openPage closes its context (and frees its slot) when a step after opening it fails, e.g. a refused navigation: callers without registerCleanup (runInBrowser) had nothing to close, and after openPageLimit such failures every later openPage waited forever. runInBrowser races the page's load and script against a timeout (default 25 s, below the tiers' 30 s test timeout; run(script, { timeout })), as runInPage does. Two controls fail before the fix (both time out) and pass after it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… for the function case it tests

Review S8. The header and fixture lose the class case the slice does not test. The user-side chunk group now leaves out every module id with a query, instead of matching the compiler's split query (`tsr-split=export---` is #8817's id format), and 'unreported' means no warning names the route file, instead of a match on the warning's text.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…-fixes

Review S9. Its two 'is reported nothing' tests pass on main only because main has no such report; their positive cases fail on main. The file comes with the PR that brings the reports.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…Yuku with a compiler

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…hout design-doc references

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant