@@ -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+
96113export type { RscPluginManager }
97114
98115class 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