Skip to content

fix(start-plugin-core): preload transitive static imports and fix Rsbuild shared-chunk CSS - #8695

Merged
schiller-manuel merged 3 commits into
mainfrom
fix/start-manifest-static-import-closure
Oct 12, 2026
Merged

schiller-manuel merged 3 commits into
mainfrom
fix/start-manifest-static-import-closure

Conversation

@LadyBluenotes

@LadyBluenotes LadyBluenotes commented Oct 12, 2026 •

Copy link
Copy Markdown
Member

🎯 Changes

imports on a normalized client chunk was read as a complete list when building route preloads, but walked as a graph everywhere else. Rolldown and Rsbuild list direct imports only, so a route lost every second-level modulepreload, and with Rsbuild shared chunks the sibling-based import list carried unrelated route CSS into the SSR response or dropped the shared CSS.

  • manifestBuilder.ts: one memoized depth-first walk over the static import graph now serves both preloads (discovery order) and stylesheets (dependencies first), replacing the flat imports read for preloads and the separate recursive CSS collector. Each chunk in an import cycle now sees the whole cycle instead of a partially cached result.
  • rsbuild/normalized-client-build.ts: derive imports from active module dependencies instead of chunk-group siblings, including concatenated modules and CSS-only chunks. Based on fix(start): collect Rsbuild SSR styles from static dependencies #8466 by @SyMind. Static dependency resolution is memoized per chunk.
  • Document the imports contract on NormalizedClientChunk.
  • Tests: real Rspack fixtures for shared, second-level and initial vendor chunks; a direct-imports-only manifest test (from fix(start-plugin-core): preload transitive static imports of route chunks #8520 by @TiagoGranelli); the css-modules e2e now has shared chunks and runs on Vite and Rsbuild with JavaScript disabled.

Fixes #8415, fixes #8511.

✅ Checklist

  • I have followed the steps in the Contributing guide.
  • I have tested code changes locally with the relevant test commands, or tests do not apply to this pull request.
  • I fully understand the code in this pull request.

🚀 Release Impact

  • This change affects published code, and I have generated a changeset.
  • This change is docs/CI/dev-only (no release).

Summary by CodeRabbit

  • Bug Fixes
    • Improved route preloading in Rsbuild builds so pages include assets from their static import chains while dynamically loaded content remains separate.
    • Improved stylesheet handling for shared and route-specific CSS, helping pages load relevant styles without unrelated route styles.
  • New Features
    • Added Rsbuild build coverage for CSS modules, including checks for route styles, shared styles, and preload behavior.

@changeset-bot

changeset-bot Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 504f08f

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 5 packages
Name Type
@tanstack/start-plugin-core Patch
@tanstack/react-start-rsc Patch
@tanstack/react-start Patch
@tanstack/solid-start Patch
@tanstack/vue-start Patch

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

@coderabbitai

coderabbitai Bot commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: TanStack/router/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 174a2152-c6ce-40d4-a341-a7413fd85200
📥 Commits

Reviewing files that changed from the base of the PR and between 1420d00 and 504f08f.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (4)
  • packages/start-plugin-core/src/rsbuild/normalized-client-build.ts
  • packages/start-plugin-core/src/start-manifest-plugin/manifestBuilder.ts
  • packages/start-plugin-core/src/types.ts
  • packages/start-plugin-core/tests/start-manifest-plugin/manifestBuilder.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/start-plugin-core/src/types.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 7 remain after this review.

📝 Walkthrough

Walkthrough

Rsbuild chunk normalization now derives static imports and CSS from module dependencies. Manifest generation traverses transitive static imports for route preloads. The CSS Modules E2E app adds Rsbuild support and production checks.

Changes

Static chunk assets and preloads

Layer / File(s) Summary
Normalize Rsbuild static dependencies
packages/start-plugin-core/src/rsbuild/normalized-client-build.ts, packages/start-plugin-core/tests/rsbuild/normalized-client-build.test.ts
Normalized chunk imports now reflect active static dependencies rather than sibling chunks. CSS-only dependencies contribute styles before importer CSS. Real Rspack tests cover dependency handling, CSS ordering, and inline CSS.
Traverse static imports for route preloads
packages/start-plugin-core/src/start-manifest-plugin/manifestBuilder.ts, packages/start-plugin-core/src/types.ts, packages/start-plugin-core/src/vite/start-manifest-plugin/plugin.ts, packages/start-plugin-core/tests/start-manifest-plugin/manifestBuilder.test.ts, .changeset/start-manifest-static-import-closure.md
Manifest preloads now include transitive static imports; dynamic imports remain excluded. CSS links are collected in dependency-first order. Inline CSS URLs use joined base paths. Tests cover cycles and preload contents.
Add shared and route-specific CSS fixtures
e2e/react-start/css-modules/src/components/*, e2e/react-start/css-modules/src/routes/*, e2e/react-start/css-modules/src/styles/*, e2e/react-start/css-modules/src/utils/formatTitle.ts, e2e/react-start/css-modules/src/routeTree.gen.ts
The E2E app adds a shared Header and formatting utility, plus Alpha, Beta, and Gamma routes with route-specific styles. The generated route tree registers the new routes.
Configure and test production builds
e2e/react-start/css-modules/package.json, e2e/react-start/css-modules/{playwright.config.ts,rsbuild.config.ts,vite.config.ts}, e2e/react-start/css-modules/tests/shared-css.prod.spec.ts
The E2E app adds Rsbuild build configuration and production checks for CSS isolation, shared-header styling, and script preloads. Playwright and Vite builds can use E2E_DIST_DIR.

Priority: ➖ Normal

Estimated code review effort: 4 (Complex) | ~40 minutes

Change: Bug fix · Severity of issue fixed: Medium

Merge Risk: ⚪ Minimal · up to 504f0

Route preloads now include the full chain of static imports, and Rsbuild shared-chunk CSS is limited to dependencies the route actually uses. Tests cover both changes, and no concrete regression was identified, so this is ready to merge.

Pre-merge checks · Passed 4 · Failed 1

Failed Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 40.91% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 22 functions across 16 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks (4 passed)
Check name Status Explanation
Linked Issues check Passed The PR satisfies both active linked issues. For #8511, manifestBuilder.ts traverses the direct static-import graph transitively and uses the traversal for route preloads. The manifest test covers di…
Out of Scope Changes check Passed The changes remain within the scope of #8415 and #8511. The NormalizedClientChunk.imports documentation, changeset, manifest resolver refactor, fixture changes, and automated tests support the stati…
Title check Passed The title clearly and concisely identifies both primary fixes: transitive static-import preloads and Rsbuild shared-chunk CSS.
Description check Passed The description includes the required Changes, Checklist, and Release Impact sections. It explains the motivation, implementation, tests, linked issues, and changeset status. All checklist items are a…
  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

LadyBluenotes and others added 2 commits October 13, 2026 00:49
…uild shared-chunk CSS

Route preloads read a chunk's `imports` as a complete list, which only
holds when the bundler hoists transitive imports. Walk the static import
graph instead, and derive Rsbuild chunk imports from the module graph
rather than chunk-group siblings so shared chunks stop attaching
unrelated route CSS to the SSR response.

Fixes #8415
Fixes #8511
…s and CSS

The manifest builder walked the static import graph twice, once breadth-first
for preloads and once recursively for stylesheets. A single memoized
depth-first walk now records discovered file names for preloads and chunks in
post-order for stylesheets, which also keeps every chunk in an import cycle
seeing the whole cycle instead of a partially cached result.

The Rsbuild adapter resolved static dependency chunks again for every CSS-only
chunk reached from each importer; the resolution is now memoized per chunk.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@schiller-manuel
schiller-manuel force-pushed the fix/start-manifest-static-import-closure branch from 1420d00 to 6e3bda7 Compare October 12, 2026 22:50
@socket-security

socket-security Bot commented Oct 12, 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-sass@​2.0.11001008094100

View full report

Rollup is no longer a supported client bundler, so the `imports` contract is
described in terms of the direct-imports-only lists Rolldown and Rsbuild emit.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@nx-cloud

nx-cloud Bot commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

View your CI Pipeline Execution ↗ for commit 504f08f

Command Status Duration Result
nx affected --targets=test:eslint,test:unit,tes... ❌ Failed 8m 49s View ↗
nx run-many --target=build --exclude=examples/*... ✅ Succeeded 19s View ↗

☁️ Nx Cloud last updated this comment at 2026-10-12 23:05:55 UTC

@github-actions

Copy link
Copy Markdown
Contributor

Bundle Size Benchmarks

  • Commit: 6a8c63b1c9db
  • Measured at: 2026-10-12T22:58:35.648Z
  • Baseline source: history:f243c61e95da
  • 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 100.3 KiB
0 B
100.2 KiB
-2 B
313.2 KiB
+4 B
86.6 KiB
-42 B
▁▁▁▁▁▁▁████
react-start.rsbuild.minimal-iife 100.7 KiB
-5 B
100.6 KiB
-7 B
314.2 KiB
+3 B
87.0 KiB
+18 B
▁▁▁▁▁▁▁████▄
react-start.rsbuild.full 103.5 KiB
+3 B
103.3 KiB
+1 B
322.9 KiB
+4 B
89.4 KiB
+49 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.

@github-actions

Copy link
Copy Markdown
Contributor

🚀 Changeset Version Preview

14 package(s) bumped directly, 9 bumped as dependents.

🟨 Minor bumps

Package Version Reason
@tanstack/react-start 1.168.61 → 1.169.0 Changeset
@tanstack/solid-start 1.168.58 → 1.169.0 Changeset
@tanstack/vue-start 1.168.57 → 1.169.0 Changeset

🟩 Patch bumps

Package Version Reason
@tanstack/react-start-rsc 0.1.60 → 0.1.61 Changeset
@tanstack/react-start-server 1.167.47 → 1.167.48 Changeset
@tanstack/router-core 1.171.35 → 1.171.36 Changeset
@tanstack/router-generator 1.167.41 → 1.167.42 Changeset
@tanstack/router-plugin 1.168.43 → 1.168.44 Changeset
@tanstack/solid-start-server 1.167.45 → 1.167.46 Changeset
@tanstack/start-client-core 1.170.35 → 1.170.36 Changeset
@tanstack/start-plugin-core 1.171.50 → 1.171.51 Changeset
@tanstack/start-server-core 1.169.40 → 1.169.41 Changeset
@tanstack/start-storage-context 1.167.37 → 1.167.38 Changeset
@tanstack/vue-start-server 1.167.45 → 1.167.46 Changeset
@tanstack/react-router 1.170.42 → 1.170.43 Dependent
@tanstack/react-start-client 1.168.40 → 1.168.41 Dependent
@tanstack/router-cli 1.167.41 → 1.167.42 Dependent
@tanstack/router-vite-plugin 1.167.43 → 1.167.44 Dependent
@tanstack/solid-router 1.170.39 → 1.170.40 Dependent
@tanstack/solid-start-client 1.168.38 → 1.168.39 Dependent
@tanstack/start-static-server-functions 1.167.40 → 1.167.41 Dependent
@tanstack/vue-router 1.170.38 → 1.170.39 Dependent
@tanstack/vue-start-client 1.167.41 → 1.167.42 Dependent

@pkg-pr-new

pkg-pr-new Bot commented Oct 12, 2026

Copy link
Copy Markdown
More templates

@tanstack/arktype-adapter

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

@tanstack/eslint-plugin-router

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

@tanstack/eslint-plugin-start

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

@tanstack/history

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

@tanstack/react-router

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

@tanstack/react-router-devtools

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

@tanstack/react-router-ssr-query

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

@tanstack/react-start

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

@tanstack/react-start-client

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

@tanstack/react-start-rsc

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

@tanstack/react-start-server

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

@tanstack/router-cli

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

@tanstack/router-core

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

@tanstack/router-devtools

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

@tanstack/router-devtools-core

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

@tanstack/router-generator

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

@tanstack/router-plugin

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

@tanstack/router-ssr-query-core

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

@tanstack/router-utils

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

@tanstack/router-vite-plugin

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

@tanstack/solid-router

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

@tanstack/solid-router-devtools

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

@tanstack/solid-router-ssr-query

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

@tanstack/solid-start

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

@tanstack/solid-start-client

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

@tanstack/solid-start-server

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

@tanstack/start-client-core

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

@tanstack/start-fn-stubs

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

@tanstack/start-plugin-core

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

@tanstack/start-server-core

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

@tanstack/start-static-server-functions

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

@tanstack/start-storage-context

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

@tanstack/valibot-adapter

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

@tanstack/virtual-file-routes

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

@tanstack/vue-router

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

@tanstack/vue-router-devtools

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

@tanstack/vue-router-ssr-query

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

@tanstack/vue-start

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

@tanstack/vue-start-client

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

@tanstack/vue-start-server

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

@tanstack/zod-adapter

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

commit: 504f08f

@schiller-manuel
schiller-manuel merged commit 4104b8e into main Oct 12, 2026
16 of 17 checks passed
@schiller-manuel
schiller-manuel deleted the fix/start-manifest-static-import-closure branch October 12, 2026 23:07
@github-actions github-actions Bot mentioned this pull request Oct 12, 2026
@codspeed

codspeed Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

Merging this PR will improve performance by 3.61%

ℹ️ 3 benchmarks have no flame graph

The flamegraph could not be generated because too much time was spent in runtime internals, making the visualization not useful for performance analysis.

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

⚡ 1 improved benchmark
✅ 193 untouched benchmarks
⏩ 3 skipped benchmarks1

Performance Changes

Mode Benchmark BASE HEAD Efficiency
⚡ Memory mem client navigation-churn (solid) 95 KB 91.6 KB +3.61%

Tip

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


Comparing fix/start-manifest-static-import-closure (504f08f) with main (f243c61)

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. ↩

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

Projects

None yet

2 participants