Skip to content

test(rsc): HMR e2e for a route component co-located with a server fn (canary for #7618 / vitejs/vite-plugin-react#1248) - #7621

Closed
sreetamdas wants to merge 1 commit into
TanStack:mainfrom
sreetamdas:fix/rsc-serverfn-fast-refresh
Closed

test(rsc): HMR e2e for a route component co-located with a server fn (canary for #7618 / vitejs/vite-plugin-react#1248)#7621
sreetamdas wants to merge 1 commit into
TanStack:mainfrom
sreetamdas:fix/rsc-serverfn-fast-refresh

Conversation

@sreetamdas

@sreetamdas sreetamdas commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Description

Adds a dev-mode HMR e2e for a TanStack Start RSC route whose file co-locates a createServerFn with the route component, asserting the component Fast Refreshes on edit (and preserves local state).

This is intentionally opened as a draft / CI canary: the test fails on main today because it reproduces a real bug — editing such a route component emits only an (rsc) hmr update …?tss-serverfn-split with no client update, so the DOM never changes. It will go green once the upstream @vitejs/plugin-rsc fix lands and the dependency is bumped. So the PR's CI status is a direct signal for "is the issue resolved yet?".

What's here

  • e2e/react-start/rsc/src/routes/rsc-hmr-serverfn.tsx — fixture: createServerFn + route component (marker + counter) in one file.
  • e2e/react-start/rsc/tests-hmr/rsc-hmr.spec.ts — edits the marker, asserts it updates and the counter survives (HMR, not reload).
  • e2e/react-start/rsc/playwright.hmr.config.ts — a dev-mode Playwright lane (the existing rsc e2e runs the built/prod server, which can't exercise HMR), plus a test:e2e:hmr script.

Needs guidance
The new lane isn't wired into the nx/CI e2e matrix yet — HMR needs a dev server, and the existing dev-mode hmr e2e is non-RSC. Happy to integrate it wherever you'd prefer (extend the hmr suite to RSC, or register this as its own CI e2e project). Flagging since it won't run in CI as-is.

Adds a dev-mode Playwright lane (playwright.hmr.config.ts + tests-hmr/) and a
fixture route (rsc-hmr-serverfn.tsx) that co-locates a createServerFn with the
route component, then asserts the component Fast Refreshes on edit.

This currently FAILS on main: editing the component only emits an (rsc) hmr
update for ?tss-serverfn-split, with no client update. It passes once the
upstream plugin-rsc fix lands and the dependency is bumped.

Refs TanStack#7618, vitejs/vite-plugin-react#1248
@coderabbitai

coderabbitai Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 64494c33-03c3-4cc9-aea7-48389c14b370

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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 and usage tips.

@schiller-manuel

schiller-manuel commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator

hmr is notorously hard to test in CI, so please check out how the e2e/react-start/hmr ensures that CI env with low compute and high latencies still passes.. we might just create a new e2e/react-start/rsc-hmr project for this

would be best if you create multiple routes, one with css modules, one without any css, etc.
just to ensure a broad coverage of possible scenarios

also please configure this to run in both vite and rsbuild so we ensure both build tool adapters work as expected

@sreetamdas

Copy link
Copy Markdown
Contributor Author

@schiller-manuel thank you for the response! I'll see how the test can be updated - in the meantime, I wanted to clarify that the real fix here is vitejs/vite-plugin-react#1248, this PR is really just to highlight the current breakage.

Once the fix is merged upstream, the idea is to see the test here turn green — hope that makes sense!

btw I checked locally on the rsbuild setup, and rsbuild doesn't seem to have this issue

@sreetamdas

sreetamdas commented Jul 25, 2026

Copy link
Copy Markdown
Contributor Author

Status update — the upstream fix has landed, so this canary has served its purpose.

vitejs/vite-plugin-react#1248 was merged and released in @vitejs/plugin-rsc@0.5.30. hi-ogawa replaced my e2e with his own examples/client-first + e2e/client-first.test.ts, which he described as closer to TanStack's client-first RSC architecture.

I've closed #7618 with the root-cause writeup, and opened #7900 to raise the @tanstack/react-start-rsc peer floor to >=0.5.30. That matters more than it looks: pnpm-lock.yaml here pinned 0.5.20, so the workspace was installing an affected version regardless of the >=0.5.20 range.

@schiller-manuel on your review — I'd like to do it properly rather than reshape this branch, and a few things you flagged turned out better than expected:

  • Dual toolchain is viable. I verified rsbuild + RSC + a dev server does Fast Refresh (state preserved, and a window global set before the edit survived, so it was HMR and not a reload). Worth noting the vite lane is the only one that can regress this bug — @vitejs/plugin-rsc is Vite-only, and the rsbuild path goes through Rspack/react-server-dom-rspack — so the rsbuild lane is adapter-parity coverage rather than a guard on fix(rsc): keep client HMR for client modules co-located with rsc-graph code vitejs/vite-plugin-react#1248.
  • e2e/react-start/hmr is the right harness template, as you suggested: it's already vite-ssr / rsbuild-ssr dual-toolchain in dev mode, and waitForServer + preOptimizeDevServer + createHmrFileEditor (with normalizeSource self-healing dirty fixtures) are exactly the low-compute/high-latency protections you pointed me at. e2e/react-start/rsc supplies the rsc: { enabled: true } configs. So rsc-hmr = hmr's harness + rsc's configs, serial (workers: 1, no shards, since the fixtures are mutated on disk).
  • Fixture matrix I'm planning, per your ask: co-located server fn with no CSS (the original bug), co-located + CSS module, a separate-file control, and a CSS-only edit asserting styles still hot-swap without a full reload. That last pair is the important one — the upstream guard is built entirely on classifying importers as CSS vs non-CSS, so that's the interaction most likely to regress. I hand-checked both against 0.5.30 and they pass.

One question before I put it up, since it affects how you'd want it wired: the nx playwright plugin's mode allowlist is ['ssr','spa','prerender','preview'] with no dev, which is why hmr declares mode: 'ssr' and then starts a dev server and ignores the built output. Happy to follow that same convention for rsc-hmr, or wire it differently if you'd prefer.

I'll open rsc-hmr as a fresh PR against current main rather than force-pushing over this branch — it's six weeks stale and conflicts now, and none of its files survive the rewrite. Closing this one once that's up, unless you'd rather I kept the thread here.

@sreetamdas

Copy link
Copy Markdown
Contributor Author

Superseded by #7901, which is the e2e/react-start/rsc-hmr project from @schiller-manuel's review above: separate project, hmr's CI hardening, a CSS-module route and a no-CSS route, and both the vite and rsbuild adapters.

Closing this rather than force-pushing over it — the branch is six weeks stale and none of its files survived the rewrite.

Worth recording the result from #7901 here, since it is what this canary was originally meant to demonstrate. Pinning that project to the broken @vitejs/plugin-rsc@0.5.27 fails exactly the two co-located component-edit tests, with the original symptom (only (rsc) hmr update …?tss-serverfn-split, no client update), while the CSS-only edit and the separate-file control stay green. On 0.5.30 all four pass on both adapters.

@sreetamdas sreetamdas closed this Jul 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants