1
1
import type * as Vite from "vite" ;
2
2
import { init as initEsModuleLexer } from "es-module-lexer" ;
3
3
import * as babel from "@babel/core" ;
4
+ import colors from "picocolors" ;
4
5
5
6
import { create } from "../virtual-module" ;
6
7
import * as Typegen from "../../typegen" ;
@@ -28,12 +29,14 @@ export function reactRouterRSCVitePlugin(): Vite.PluginOption[] {
28
29
let typegenWatcherPromise : Promise < Typegen . Watcher > | undefined ;
29
30
let viteCommand : Vite . ConfigEnv [ "command" ] ;
30
31
let routeIdByFile : Map < string , string > | undefined ;
32
+ let logger : Vite . Logger ;
31
33
32
34
return [
33
35
{
34
36
name : "react-router/rsc" ,
35
37
async config ( viteUserConfig , { command, mode } ) {
36
38
await initEsModuleLexer ;
39
+
37
40
viteCommand = command ;
38
41
const rootDirectory = getRootDirectory ( viteUserConfig ) ;
39
42
const watch = command === "serve" ;
@@ -58,6 +61,11 @@ export function reactRouterRSCVitePlugin(): Vite.PluginOption[] {
58
61
) ;
59
62
}
60
63
64
+ const vite = await import ( "vite" ) ;
65
+ logger = vite . createLogger ( viteUserConfig . logLevel , {
66
+ prefix : "[react-router]" ,
67
+ } ) ;
68
+
61
69
const rscEntries = getRscEntries ( ) ;
62
70
63
71
return {
@@ -147,6 +155,46 @@ export function reactRouterRSCVitePlugin(): Vite.PluginOption[] {
147
155
} ,
148
156
} ;
149
157
} ,
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
+ } ,
150
198
async buildEnd ( ) {
151
199
await configLoader . close ( ) ;
152
200
} ,
@@ -377,6 +425,17 @@ const virtual = {
377
425
basename : create ( "unstable_rsc/basename" ) ,
378
426
} ;
379
427
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
+
380
439
function getRootDirectory ( viteUserConfig : Vite . UserConfig ) {
381
440
return viteUserConfig . root ?? process . env . REACT_ROUTER_ROOT ?? process . cwd ( ) ;
382
441
}
0 commit comments