Skip to content

Deserializing client reference in server environment broken since React 19.2.1 #999

@hi-ogawa

Description

@hi-ogawa

See skipped tests in #998.

See also the patch

It looks like react now checks hasOwnProperty.call(moduleExports, metadata.name) instead of moduleExports[metadata.name], which likely broke proxy tricks such as:

// preload/preinit during getter access since `load` is cached on production
function wrapResourceProxy(mod: any, deps?: ResolvedAssetDeps) {
return new Proxy(mod, {
get(target, p, receiver) {
if (p in mod) {
if (deps) {
preloadDeps(deps)
}
}
return Reflect.get(target, p, receiver)
},
})
}

// need memoize to return stable promise from __webpack_require__
;(globalThis as any).__vite_rsc_server_require__ = memoize(
async (id: string) => {
if (id.startsWith(SERVER_DECODE_CLIENT_PREFIX)) {
id = id.slice(SERVER_DECODE_CLIENT_PREFIX.length)
id = removeReferenceCacheTag(id)
// create `registerClientReference` on the fly since there's no way to
// grab the original client reference module on ther server.
// cf. https://github.com/lazarv/react-server/blob/79e7acebc6f4a8c930ad8422e2a4a9fdacfcce9b/packages/react-server/server/module-loader.mjs#L19
// decode client reference on the server
return new Proxy({} as any, {
get(target, name, _receiver) {
if (typeof name !== 'string' || name === 'then') return
return (target[name] ??= ReactServer.registerClientReference(
() => {
throw new Error(
`Unexpectedly client reference export '${name}' is called on server`,
)
},
id,
name,
))
},
})
}
return requireModule(id)
},
)

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions