@@ -36,9 +36,14 @@ import { combineURLs } from "./combine-urls";
3636import { removeExports } from "./remove-exports" ;
3737import { importViteEsmSync , preloadViteEsm } from "./import-vite-esm-sync" ;
3838import {
39- type ReactRouterConfig ,
4039 type ResolvedReactRouterConfig ,
41- resolveReactRouterConfig ,
40+ createConfigLoader ,
41+ } from "../config/config" ;
42+ import {
43+ // todo: clean these up
44+ // type ReactRouterConfig,
45+ // type ResolvedReactRouterConfig,
46+ // resolveReactRouterConfig,
4247 resolveEntryFiles ,
4348 resolvePublicPath ,
4449} from "./config" ;
@@ -418,16 +423,12 @@ let deepFreeze = (o: any) => {
418423 return o ;
419424} ;
420425
421- type ReactRouterVitePlugin = ( config ?: ReactRouterConfig ) => Vite . Plugin [ ] ;
426+ type ReactRouterVitePlugin = ( ) => Vite . Plugin [ ] ;
422427/**
423428 * React Router [Vite plugin.](https://vitejs.dev/guide/using-plugins.html)
424429 */
425- export const reactRouterVitePlugin : ReactRouterVitePlugin = ( _config ) => {
426- let reactRouterUserConfig = _config ?? { } ;
427-
428- // Prevent mutations to the user config
429- reactRouterUserConfig = deepFreeze ( reactRouterUserConfig ) ;
430-
430+ export const reactRouterVitePlugin : ReactRouterVitePlugin = ( ) => {
431+ let rootDirectory : string ;
431432 let viteCommand : Vite . ResolvedConfig [ "command" ] ;
432433 let viteUserConfig : Vite . UserConfig ;
433434 let viteConfigEnv : Vite . ConfigEnv ;
@@ -442,24 +443,32 @@ export const reactRouterVitePlugin: ReactRouterVitePlugin = (_config) => {
442443 // change or route file addition/removal.
443444 let ctx : ReactRouterPluginContext ;
444445
446+ let reactRouterConfigLoader : Awaited < ReturnType < typeof createConfigLoader > > ;
447+
448+ let logger : Vite . Logger ;
449+
450+ let firstLoad = true ;
451+
445452 /** Mutates `ctx` as a side-effect */
446453 let updatePluginContext = async ( {
447454 routeConfigChanged = false ,
448455 } : {
449456 routeConfigChanged ?: boolean ;
450457 } = { } ) : Promise < void > => {
451- let rootDirectory =
452- viteUserConfig . root ?? process . env . REACT_ROUTER_ROOT ?? process . cwd ( ) ;
453-
454458 invariant ( routesViteNodeContext ) ;
455- let reactRouterConfig = await resolveReactRouterConfig ( {
456- rootDirectory,
457- reactRouterUserConfig,
458- routeConfigChanged,
459- viteUserConfig,
460- viteCommand,
461- routesViteNodeContext,
462- } ) ;
459+
460+ let reactRouterConfig : ResolvedReactRouterConfig ;
461+ let reactRouterConfigResult = await reactRouterConfigLoader . getConfig ( ) ;
462+
463+ if ( reactRouterConfigResult . ok ) {
464+ reactRouterConfig = reactRouterConfigResult . value ;
465+ } else {
466+ logger . error ( reactRouterConfigResult . error ) ;
467+ if ( firstLoad ) {
468+ process . exit ( 1 ) ;
469+ }
470+ return ;
471+ }
463472
464473 let { entryClientFilePath, entryServerFilePath } = await resolveEntryFiles ( {
465474 rootDirectory,
@@ -480,6 +489,8 @@ export const reactRouterVitePlugin: ReactRouterVitePlugin = (_config) => {
480489 }
481490 : { isSsrBuild : false } ;
482491
492+ firstLoad = false ;
493+
483494 ctx = {
484495 reactRouterConfig,
485496 rootDirectory,
@@ -749,6 +760,18 @@ export const reactRouterVitePlugin: ReactRouterVitePlugin = (_config) => {
749760 viteConfigEnv = _viteConfigEnv ;
750761 viteCommand = viteConfigEnv . command ;
751762
763+ logger = vite . createLogger ( viteUserConfig . logLevel , {
764+ prefix : "[react-router]" ,
765+ } ) ;
766+
767+ rootDirectory =
768+ viteUserConfig . root ?? process . env . REACT_ROUTER_ROOT ?? process . cwd ( ) ;
769+
770+ reactRouterConfigLoader = await createConfigLoader ( {
771+ rootDirectory,
772+ command : viteCommand === "serve" ? "dev" : "build" ,
773+ } ) ;
774+
752775 routesViteNodeContext = await ViteNode . createContext ( {
753776 root : viteUserConfig . root ,
754777 mode : viteConfigEnv . mode ,
@@ -1062,47 +1085,32 @@ export const reactRouterVitePlugin: ReactRouterVitePlugin = (_config) => {
10621085 } ,
10631086 } ) ;
10641087
1065- // Invalidate virtual modules and update cached plugin config via file watcher
1066- viteDevServer . watcher . on ( "all" , async ( eventName , rawFilepath ) => {
1067- let { normalizePath } = importViteEsmSync ( ) ;
1068- let filepath = normalizePath ( rawFilepath ) ;
1088+ reactRouterConfigLoader . onChange (
1089+ async ( { result , routeConfigChanged } ) => {
1090+ if ( result . ok ) {
1091+ let lastReactRouterConfig = ctx . reactRouterConfig ;
10691092
1070- let appFileAddedOrRemoved =
1071- ( eventName === "add" || eventName === "unlink" ) &&
1072- filepath . startsWith (
1073- normalizePath ( ctx . reactRouterConfig . appDirectory )
1074- ) ;
1075-
1076- invariant ( viteConfig ?. configFile ) ;
1077- let viteConfigChanged =
1078- eventName === "change" &&
1079- filepath === normalizePath ( viteConfig . configFile ) ;
1080-
1081- let routeConfigChanged = Boolean (
1082- routesViteNodeContext ?. devServer ?. moduleGraph . getModuleById (
1083- filepath
1084- )
1085- ) ;
1086-
1087- if ( routeConfigChanged || appFileAddedOrRemoved ) {
1088- routesViteNodeContext ?. devServer ?. moduleGraph . invalidateAll ( ) ;
1089- routesViteNodeContext ?. runner ?. moduleCache . clear ( ) ;
1090- }
1091-
1092- if (
1093- appFileAddedOrRemoved ||
1094- viteConfigChanged ||
1095- routeConfigChanged
1096- ) {
1097- let lastReactRouterConfig = ctx . reactRouterConfig ;
1093+ if ( routeConfigChanged ) {
1094+ logger . info ( colors . green ( "Route config changed." ) , {
1095+ clear : true ,
1096+ timestamp : true ,
1097+ } ) ;
1098+ }
10981099
1099- await updatePluginContext ( { routeConfigChanged } ) ;
1100+ await updatePluginContext ( { routeConfigChanged } ) ;
11001101
1101- if ( ! isEqualJson ( lastReactRouterConfig , ctx . reactRouterConfig ) ) {
1102+ if ( ! isEqualJson ( lastReactRouterConfig , ctx . reactRouterConfig ) ) {
1103+ invalidateVirtualModules ( viteDevServer ) ;
1104+ }
1105+ } else {
11021106 invalidateVirtualModules ( viteDevServer ) ;
1107+ logger . error ( result . error , {
1108+ clear : true ,
1109+ timestamp : true ,
1110+ } ) ;
11031111 }
11041112 }
1105- } ) ;
1113+ ) ;
11061114
11071115 return ( ) => {
11081116 // Let user servers handle SSR requests in middleware mode,
@@ -1236,6 +1244,7 @@ export const reactRouterVitePlugin: ReactRouterVitePlugin = (_config) => {
12361244 async buildEnd ( ) {
12371245 await viteChildCompiler ?. close ( ) ;
12381246 await routesViteNodeContext ?. devServer ?. close ( ) ;
1247+ await reactRouterConfigLoader . close ( ) ;
12391248 } ,
12401249 } ,
12411250 {
@@ -1739,7 +1748,7 @@ async function getRouteMetadata(
17391748
17401749async function getPrerenderBuildAndHandler (
17411750 viteConfig : Vite . ResolvedConfig ,
1742- reactRouterConfig : Awaited < ReturnType < typeof resolveReactRouterConfig > > ,
1751+ reactRouterConfig : ResolvedReactRouterConfig ,
17431752 serverBuildDirectory : string
17441753) {
17451754 let serverBuildPath = path . join (
@@ -1756,7 +1765,7 @@ async function getPrerenderBuildAndHandler(
17561765
17571766async function handleSpaMode (
17581767 viteConfig : Vite . ResolvedConfig ,
1759- reactRouterConfig : Awaited < ReturnType < typeof resolveReactRouterConfig > > ,
1768+ reactRouterConfig : ResolvedReactRouterConfig ,
17601769 serverBuildDirectory : string ,
17611770 clientBuildDirectory : string
17621771) {
@@ -1784,7 +1793,7 @@ async function handleSpaMode(
17841793
17851794async function handlePrerender (
17861795 viteConfig : Vite . ResolvedConfig ,
1787- reactRouterConfig : Awaited < ReturnType < typeof resolveReactRouterConfig > > ,
1796+ reactRouterConfig : ResolvedReactRouterConfig ,
17881797 serverBuildDirectory : string ,
17891798 clientBuildDirectory : string
17901799) {
@@ -1921,7 +1930,7 @@ async function prerenderData(
19211930 handler : RequestHandler ,
19221931 prerenderPath : string ,
19231932 clientBuildDirectory : string ,
1924- reactRouterConfig : Awaited < ReturnType < typeof resolveReactRouterConfig > > ,
1933+ reactRouterConfig : ResolvedReactRouterConfig ,
19251934 viteConfig : Vite . ResolvedConfig ,
19261935 requestInit : RequestInit
19271936) {
@@ -1949,7 +1958,7 @@ async function prerenderRoute(
19491958 handler : RequestHandler ,
19501959 prerenderPath : string ,
19511960 clientBuildDirectory : string ,
1952- reactRouterConfig : Awaited < ReturnType < typeof resolveReactRouterConfig > > ,
1961+ reactRouterConfig : ResolvedReactRouterConfig ,
19531962 viteConfig : Vite . ResolvedConfig ,
19541963 requestInit : RequestInit
19551964) {
@@ -1979,7 +1988,7 @@ async function prerenderResourceRoute(
19791988 handler : RequestHandler ,
19801989 prerenderPath : string ,
19811990 clientBuildDirectory : string ,
1982- reactRouterConfig : Awaited < ReturnType < typeof resolveReactRouterConfig > > ,
1991+ reactRouterConfig : ResolvedReactRouterConfig ,
19831992 viteConfig : Vite . ResolvedConfig ,
19841993 requestInit : RequestInit
19851994) {
@@ -2003,7 +2012,7 @@ async function prerenderResourceRoute(
20032012async function prerenderManifest (
20042013 build : ServerBuild ,
20052014 clientBuildDirectory : string ,
2006- reactRouterConfig : Awaited < ReturnType < typeof resolveReactRouterConfig > > ,
2015+ reactRouterConfig : ResolvedReactRouterConfig ,
20072016 viteConfig : Vite . ResolvedConfig
20082017) {
20092018 let normalizedPath = `${ reactRouterConfig . basename } /__manifest` . replace (
0 commit comments