Skip to content

Commit ef5495f

Browse files
hi-ogawaclaude
andcommitted
refactor(plugin-rsc): move onClientReference notification into wrapResourceProxy
Consolidate client reference notification by moving it into the resource proxy getter, which is called on every export access (not memoized by React). This eliminates the separate `onLoad` callback mechanism. - Remove `onLoad` option from `setRequireModule` - Add `id` parameter to `wrapResourceProxy` and make `deps` required - Notify `onClientReference` early in `load` (production) alongside preload - Notify `onClientReference` in proxy getter for per-request asset collection Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 8dc7e5f commit ef5495f

2 files changed

Lines changed: 14 additions & 35 deletions

File tree

packages/plugin-rsc/src/core/ssr.ts

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,14 @@ let init = false
66

77
export function setRequireModule(options: {
88
load: (id: string) => unknown
9-
/**
10-
* Called EVERY time a module is requested
11-
* @experimental
12-
*/
13-
onLoad?: (id: string) => void
149
}): void {
1510
if (init) return
1611
init = true
1712

1813
const requireModule = memoize((id: string) => {
1914
return options.load(removeReferenceCacheTag(id))
2015
})
21-
22-
const clientRequire = (id: string) => {
23-
const cleanId = removeReferenceCacheTag(id)
24-
options.onLoad?.(cleanId)
25-
return requireModule(id)
26-
}
27-
;(globalThis as any).__vite_rsc_client_require__ = clientRequire
16+
;(globalThis as any).__vite_rsc_client_require__ = requireModule
2817

2918
setInternalRequire()
3019
}

packages/plugin-rsc/src/ssr.tsx

Lines changed: 13 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -47,43 +47,33 @@ function initialize(): void {
4747
const modCss = await import(
4848
/* @vite-ignore */ '/@id/__x00__' + toCssVirtual({ id, type: 'ssr' })
4949
)
50-
return wrapResourceProxy(mod, { js: [], css: modCss.default })
50+
return wrapResourceProxy(mod, id, { js: [], css: modCss.default })
5151
} else {
5252
const import_ = clientReferences.default[id]
5353
if (!import_) {
5454
throw new Error(`client reference not found '${id}'`)
5555
}
56-
const deps = assetsManifest.clientReferenceDeps[id]
57-
// kick off preload before initial async import, which is not sync-cached
58-
if (deps) {
59-
preloadDeps(deps)
60-
}
56+
const deps =
57+
assetsManifest.clientReferenceDeps[id] ??
58+
({ js: [], css: [] } as const)
59+
// kick off preload/notify before initial async import, which is not sync-cached
60+
preloadDeps(deps)
61+
onClientReference?.({ id, deps })
6162
const mod: any = await import_()
62-
return wrapResourceProxy(mod, deps)
63-
}
64-
},
65-
// Called EVERY time a module is requested (not memoized).
66-
// Notify framework callback for per-request asset collection.
67-
onLoad: (id) => {
68-
if (!import.meta.env.__vite_rsc_build__) return
69-
if (onClientReference) {
70-
const deps = assetsManifest.clientReferenceDeps[id]
71-
if (deps) {
72-
onClientReference({ id, deps: { js: deps.js, css: deps.css } })
73-
}
63+
return wrapResourceProxy(mod, id, deps)
7464
}
7565
},
7666
})
7767
}
7868

79-
// preload/preinit during getter access since `load` is cached on production
80-
function wrapResourceProxy(mod: any, deps?: ResolvedAssetDeps) {
69+
// preload/preinit during getter access since `load` is cached on production.
70+
// also notify `onClientReference` callback here since module export access is not memoized by React.
71+
function wrapResourceProxy(mod: any, id: string, deps: ResolvedAssetDeps) {
8172
return new Proxy(mod, {
8273
get(target, p, receiver) {
8374
if (p in mod) {
84-
if (deps) {
85-
preloadDeps(deps)
86-
}
75+
preloadDeps(deps)
76+
onClientReference?.({ id, deps })
8777
}
8878
return Reflect.get(target, p, receiver)
8979
},

0 commit comments

Comments
 (0)