fix(start-plugin-core): strip middleware chain on client builds#7125
fix(start-plugin-core): strip middleware chain on client builds#7125afonsojramos wants to merge 1 commit intoTanStack:mainfrom
Conversation
📝 WalkthroughWalkthrough
Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~8 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
Bundle Size Benchmarks
Trend sparkline is historical gzip bytes ending with this PR measurement; lower is better. |
The `createServerFn` compiler correctly replaces `.handler(fn)` with
`.handler(createClientRpc('hash'))` for client builds, but leaves the
`.middleware([...])` chain intact. This keeps server-only imports
(auth middleware, DB connections, etc.) alive in the client bundle.
With esbuild (Vite 7), these dead references were tree-shaken. With
Rolldown (Vite 8), the middleware functions remain as live references,
pulling the entire server dependency tree into the client bundle. This
causes runtime crashes like `ReferenceError: Buffer is not defined`
when Node.js-only packages (e.g. `postgres`) end up in the browser.
The fix strips `.middleware()` calls on client builds, matching the
existing pattern used for `.inputValidator()`. Since middleware only
executes server-side and the client RPC stub skips it entirely, the
middleware chain is dead code on the client.
289c86d to
69c3eb3
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (1)
packages/start-plugin-core/tests/compiler.test.ts (1)
464-485: Strengthen server assertion to verify middleware chain preservation.Checking only
authMiddlewarecan still pass if the import remains but.middleware()is accidentally stripped. Add an explicit assertion for the middleware call shape.Suggested test tightening
expect(result).not.toBeNull() // Server should keep middleware intact + expect(result!.code).toContain('.middleware(') expect(result!.code).toContain('authMiddleware')🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/start-plugin-core/tests/compiler.test.ts` around lines 464 - 485, The test currently only checks for the imported symbol authMiddleware which can remain even if the .middleware() call was removed; update the assertion in the 'preserves .middleware() on server builds' test (which uses createFullCompiler and compiler.compile for createServerFn) to explicitly verify the middleware call shape is preserved in result!.code (for example assert the string '.middleware(' or the exact '.middleware([authMiddleware])' appears), so the test fails if .middleware() is stripped while the import remains.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@packages/start-plugin-core/tests/compiler.test.ts`:
- Around line 464-485: The test currently only checks for the imported symbol
authMiddleware which can remain even if the .middleware() call was removed;
update the assertion in the 'preserves .middleware() on server builds' test
(which uses createFullCompiler and compiler.compile for createServerFn) to
explicitly verify the middleware call shape is preserved in result!.code (for
example assert the string '.middleware(' or the exact
'.middleware([authMiddleware])' appears), so the test fails if .middleware() is
stripped while the import remains.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 212ee0df-7ba8-4bbc-9bab-80b61e622879
📒 Files selected for processing (2)
packages/start-plugin-core/src/start-compiler-plugin/handleCreateServerFn.tspackages/start-plugin-core/tests/compiler.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/start-plugin-core/src/start-compiler-plugin/handleCreateServerFn.ts
Summary
The
createServerFncompiler correctly replaces.handler(fn)with.handler(createClientRpc('hash'))for client builds, and strips.inputValidator()— but leaves the.middleware([...])chain intact. This keeps server-only imports (auth middleware, DB connections, etc.) alive in the client bundle.With esbuild (Vite 7/rolldown-vite), these dead references were tree-shaken. With Rolldown (Vite 8), the middleware functions remain as live symbol references, pulling the entire server dependency tree into the client bundle. This causes runtime crashes like:
...when Node.js-only packages (e.g.
postgres) end up in the browser, preventinghydrateRootfrom completing.Fix
Strip
.middleware()calls on client builds usingstripMethodCall, matching the existing pattern for.inputValidator(). Since middleware only executes server-side and the client RPC stub skips it entirely, the middleware chain is dead code on the client.Before (client build output):
After (client build output):
This makes the middleware imports (
requireAuth,requirePermission) unreferenced, allowing the bundler to tree-shake the entire server dependency chain.Tests
Added two tests to
compiler.test.ts:strips .middleware() from createServerFn on client builds— verifies.middleware()and the middleware import are removed from client outputpreserves .middleware() on server builds— verifies server builds keep middleware intactContext
createServerFn().middleware([...])with Vite 8Summary by CodeRabbit
Bug Fixes
Tests