Skip to content

Commit bb0a5d7

Browse files
Copilothi-ogawa
andcommitted
Add dynamic react-server-dom-webpack resolution
- Add getReactServerDomPackageName() helper to detect user's package - Create alias plugin to redirect vendored imports to user's package - Update config to use dynamic package name in optimizeDeps Co-authored-by: hi-ogawa <[email protected]>
1 parent 29d17b3 commit bb0a5d7

File tree

1 file changed

+60
-4
lines changed

1 file changed

+60
-4
lines changed

packages/plugin-rsc/src/plugin.ts

Lines changed: 60 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,23 @@ function resolvePackage(name: string) {
9393
return pathToFileURL(require.resolve(name)).href
9494
}
9595

96+
/**
97+
* Try to resolve react-server-dom-webpack from user's project.
98+
* Returns the package name to use: either 'react-server-dom-webpack' if found in user's project,
99+
* or the vendored version otherwise.
100+
*/
101+
function getReactServerDomPackageName(root: string): string {
102+
try {
103+
const userRequire = createRequire(path.join(root, 'package.json'))
104+
// Try to resolve the package from user's project
105+
userRequire.resolve('react-server-dom-webpack/package.json')
106+
return 'react-server-dom-webpack'
107+
} catch {
108+
// Fall back to vendored version if not found
109+
return REACT_SERVER_DOM_NAME
110+
}
111+
}
112+
96113
export type { RscPluginManager }
97114

98115
class RscPluginManager {
@@ -359,6 +376,11 @@ export default function vitePluginRsc(
359376
...result.ssr.noExternal.sort(),
360377
]
361378

379+
// Detect if user has react-server-dom-webpack installed
380+
const reactServerDomPackageName = getReactServerDomPackageName(
381+
config.root ?? process.cwd(),
382+
)
383+
362384
return {
363385
appType: config.appType ?? 'custom',
364386
define: {
@@ -380,7 +402,7 @@ export default function vitePluginRsc(
380402
optimizeDeps: {
381403
include: [
382404
'react-dom/client',
383-
`${REACT_SERVER_DOM_NAME}/client.browser`,
405+
`${reactServerDomPackageName}/client.browser`,
384406
],
385407
exclude: [PKG_NAME],
386408
},
@@ -406,7 +428,7 @@ export default function vitePluginRsc(
406428
'react/jsx-dev-runtime',
407429
'react-dom/server.edge',
408430
'react-dom/static.edge',
409-
`${REACT_SERVER_DOM_NAME}/client.edge`,
431+
`${reactServerDomPackageName}/client.edge`,
410432
],
411433
exclude: [PKG_NAME],
412434
},
@@ -432,8 +454,8 @@ export default function vitePluginRsc(
432454
'react-dom',
433455
'react/jsx-runtime',
434456
'react/jsx-dev-runtime',
435-
`${REACT_SERVER_DOM_NAME}/server.edge`,
436-
`${REACT_SERVER_DOM_NAME}/client.edge`,
457+
`${reactServerDomPackageName}/server.edge`,
458+
`${reactServerDomPackageName}/client.edge`,
437459
],
438460
exclude: [PKG_NAME],
439461
},
@@ -670,6 +692,40 @@ export default function vitePluginRsc(
670692
}
671693
},
672694
},
695+
{
696+
// Alias plugin to redirect vendored react-server-dom imports to user's package when available
697+
name: 'rsc:react-server-dom-alias',
698+
enforce: 'pre',
699+
async resolveId(source, importer, options) {
700+
// Only handle imports from the vendored path
701+
if (!source.startsWith(`${PKG_NAME}/vendor/react-server-dom/`)) {
702+
return null
703+
}
704+
705+
// Extract the subpath (e.g., "client.browser", "server.edge", etc.)
706+
const subpath = source.slice(
707+
`${PKG_NAME}/vendor/react-server-dom/`.length,
708+
)
709+
710+
// Get the root directory
711+
const root = this.environment?.config?.root ?? process.cwd()
712+
713+
// Check if user has react-server-dom-webpack installed
714+
const reactServerDomPackageName = getReactServerDomPackageName(root)
715+
716+
// If user has their own package, resolve to it instead
717+
if (reactServerDomPackageName === 'react-server-dom-webpack') {
718+
const newSource = `react-server-dom-webpack/${subpath}`
719+
return this.resolve(newSource, importer, {
720+
...options,
721+
skipSelf: true,
722+
})
723+
}
724+
725+
// Otherwise, let the default resolution handle the vendored path
726+
return null
727+
},
728+
},
673729
{
674730
// backward compat: `loadSsrModule(name)` implemented as `loadModule("ssr", name)`
675731
name: 'rsc:load-ssr-module',

0 commit comments

Comments
 (0)