mirror of
https://github.com/cloudflare/vinext.git
synced 2026-05-09 08:25:34 +02:00
[GH-ISSUE #1008] vinext shims with 'use client' aren't registered in clientReferenceMetaMap, causing @vitejs/plugin-rsc to crash. #221
Labels
No labels
enhancement
enhancement
good first issue
help wanted
nextjs-tracking
nextjs-tracking
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
starred/vinext#221
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @eashish93 on GitHub (May 2, 2026).
Original GitHub issue: https://github.com/cloudflare/vinext/issues/1008
Versions
vinext: 0.0.45@vitejs/plugin-rsc: 0.5.25vite: 8.0.10Symptom
Navigating to an App Router route that transitively imports any
vinext/shims/*file with'use client'(e.g. vianext/link,next/navigation,next/image,next/form,next/script) crashes the dev server with:The route renders blank, with the error only visible in the wrangler/vite terminal. Other routes that don't pull a
'use client'shim through the server-component graph load fine — which made it look route-specific and very confusing to diagnose.Root cause
@vitejs/plugin-rscgenerates a\0virtual:vite-rsc/client-package-proxy/<source>virtual module for each'use client'node_modules package transitively imported by a server component. Theloadhandler then looks up the matching entry inclientReferenceMetaMapto know which exports to re-export.The following vinext shim files all start with
'use client':vinext/dist/shims/layout-segment-context.jsvinext/dist/shims/slot.jsvinext/dist/shims/link.jsvinext/dist/shims/navigation.jsvinext/dist/shims/form.jsvinext/dist/shims/script.jsvinext/dist/shims/error-boundary.jsvinext/dist/shims/client-hook-error.jsWhen server code imports e.g.
next/link(resolved by vinext tovinext/shims/link), plugin-rsc'sresolveIdhook records the package source. Vite'sdepsOptimizerthen bundlesvinext/shims/*into a consolidated chunk that includes unrelated vinext server code. The path of the optimized chunk drifts from what plugin-rsc scanned, so itsclientReferenceMetaMaplookup misses, the load handler hitsundefined.exportNames, and the entire dev server bundle for that route crashes.After patching plugin-rsc with a defensive guard, the warning identified the actual offenders:
Reproduction shape
(I don't have a hosted repro since this is a private app, but the recipe is straightforward.)
A vinext App Router project where:
'use client'component (e.g. a chat UI)next/linkand at least one other'use client'node_modules package (e.g.sonner,swr)depsOptimizerruns in dev (default)The route bundle crashes on first request with the
exportNameserror.Workaround we shipped
Patched
@vitejs/plugin-rsc/dist/plugin-BhzHKRFo.jsline 1395 with a defensive guard that warns + falls back toexport *when the meta lookup misses, persisted viabun patch:This unblocks the dev server, but
export *doesn't preserve named-export semantics perfectly for every package. The right fix lives in vinext.Proposed fix (vinext side)
Two viable directions, either would resolve this:
rsc()plugin, also configure plugin-rsc to know about allvinext/shims/*files that ship'use client'. They're a known fixed list at vinext build time.optimizeDeps.exclude. Have vinext injectoptimizeDeps.exclude: ['vinext/shims/...'](or per-shim entries) automatically so Vite doesn't bundle them into a consolidated chunk in the first place. Users hit this without knowing they need to do it themselves, and the per-shim list will keep growing as vinext adds shims.Happy to PR option 2 if it'd help — needs guidance on the right place in
dist/index.jsto inject the config.Adjacent observation (worth a separate issue?)
@vitejs/plugin-rsc's assumption at line 1395 thatfind()always succeeds is itself a defensive-coding gap. Frameworks built on top of plugin-rsc (vinext, Waku, custom) all stand to crash the same way if any client package isn't registered. The handler should fall back gracefully + log instead of throwing. Plugin-rsc's source already has awarnInoncistentClientOptimization()helper that recommendsoptimizeDeps.exclude— it should be paired with a non-fatal load-handler fallback.(Filing this with vinext first since the actionable fix is here. Plugin-rsc maintainers want a CodeSandbox repro for upstream issues, which is harder to construct in isolation than as a vinext-on-real-app problem.)