11import type * as Vite from "vite" ;
22import { init as initEsModuleLexer } from "es-module-lexer" ;
33import * as babel from "@babel/core" ;
4+ import colors from "picocolors" ;
45
56import { create } from "../virtual-module" ;
67import * as Typegen from "../../typegen" ;
@@ -28,12 +29,14 @@ export function reactRouterRSCVitePlugin(): Vite.PluginOption[] {
2829 let typegenWatcherPromise : Promise < Typegen . Watcher > | undefined ;
2930 let viteCommand : Vite . ConfigEnv [ "command" ] ;
3031 let routeIdByFile : Map < string , string > | undefined ;
32+ let logger : Vite . Logger ;
3133
3234 return [
3335 {
3436 name : "react-router/rsc" ,
3537 async config ( viteUserConfig , { command, mode } ) {
3638 await initEsModuleLexer ;
39+
3740 viteCommand = command ;
3841 const rootDirectory = getRootDirectory ( viteUserConfig ) ;
3942 const watch = command === "serve" ;
@@ -58,6 +61,11 @@ export function reactRouterRSCVitePlugin(): Vite.PluginOption[] {
5861 ) ;
5962 }
6063
64+ const vite = await import ( "vite" ) ;
65+ logger = vite . createLogger ( viteUserConfig . logLevel , {
66+ prefix : "[react-router]" ,
67+ } ) ;
68+
6169 const rscEntries = getRscEntries ( ) ;
6270
6371 return {
@@ -147,6 +155,46 @@ export function reactRouterRSCVitePlugin(): Vite.PluginOption[] {
147155 } ,
148156 } ;
149157 } ,
158+ async configureServer ( viteDevServer ) {
159+ configLoader . onChange (
160+ async ( {
161+ result,
162+ configCodeChanged,
163+ routeConfigCodeChanged,
164+ configChanged,
165+ routeConfigChanged,
166+ } ) => {
167+ if ( ! result . ok ) {
168+ invalidateVirtualModules ( viteDevServer ) ;
169+ logger . error ( result . error , {
170+ clear : true ,
171+ timestamp : true ,
172+ } ) ;
173+ return ;
174+ }
175+
176+ // prettier-ignore
177+ let message =
178+ configChanged ? "Config changed." :
179+ routeConfigChanged ? "Route config changed." :
180+ configCodeChanged ? "Config saved." :
181+ routeConfigCodeChanged ? " Route config saved." :
182+ "Config saved" ;
183+
184+ logger . info ( colors . green ( message ) , {
185+ clear : true ,
186+ timestamp : true ,
187+ } ) ;
188+
189+ // Update shared plugin config reference
190+ config = result . value ;
191+
192+ if ( configChanged || routeConfigChanged ) {
193+ invalidateVirtualModules ( viteDevServer ) ;
194+ }
195+ } ,
196+ ) ;
197+ } ,
150198 async buildEnd ( ) {
151199 await configLoader . close ( ) ;
152200 } ,
@@ -377,6 +425,17 @@ const virtual = {
377425 basename : create ( "unstable_rsc/basename" ) ,
378426} ;
379427
428+ function invalidateVirtualModules ( viteDevServer : Vite . ViteDevServer ) {
429+ for ( const vmod of Object . values ( virtual ) ) {
430+ for ( const env of Object . values ( viteDevServer . environments ) ) {
431+ const mod = env . moduleGraph . getModuleById ( vmod . resolvedId ) ;
432+ if ( mod ) {
433+ env . moduleGraph . invalidateModule ( mod ) ;
434+ }
435+ }
436+ }
437+ }
438+
380439function getRootDirectory ( viteUserConfig : Vite . UserConfig ) {
381440 return viteUserConfig . root ?? process . env . REACT_ROUTER_ROOT ?? process . cwd ( ) ;
382441}
0 commit comments