@@ -142,6 +142,7 @@ export async function handleHMRUpdate(
142
142
updateModules ( shortFile , hmrContext . modules , timestamp , server )
143
143
}
144
144
145
+ type HasDeadEnd = boolean | string
145
146
export function updateModules (
146
147
file : string ,
147
148
modules : ModuleNode [ ] ,
@@ -152,7 +153,7 @@ export function updateModules(
152
153
const updates : Update [ ] = [ ]
153
154
const invalidatedModules = new Set < ModuleNode > ( )
154
155
const traversedModules = new Set < ModuleNode > ( )
155
- let needFullReload = false
156
+ let needFullReload : HasDeadEnd = false
156
157
157
158
for ( const mod of modules ) {
158
159
const boundaries : { boundary : ModuleNode ; acceptedVia : ModuleNode } [ ] = [ ]
@@ -165,7 +166,7 @@ export function updateModules(
165
166
}
166
167
167
168
if ( hasDeadEnd ) {
168
- needFullReload = true
169
+ needFullReload = hasDeadEnd
169
170
continue
170
171
}
171
172
@@ -184,10 +185,14 @@ export function updateModules(
184
185
}
185
186
186
187
if ( needFullReload ) {
187
- config . logger . info ( colors . green ( `page reload ` ) + colors . dim ( file ) , {
188
- clear : ! afterInvalidation ,
189
- timestamp : true ,
190
- } )
188
+ const reason =
189
+ typeof needFullReload === 'string'
190
+ ? colors . dim ( ` (${ needFullReload } )` )
191
+ : ''
192
+ config . logger . info (
193
+ colors . green ( `page reload ` ) + colors . dim ( file ) + reason ,
194
+ { clear : ! afterInvalidation , timestamp : true } ,
195
+ )
191
196
ws . send ( {
192
197
type : 'full-reload' ,
193
198
} )
@@ -254,7 +259,7 @@ function propagateUpdate(
254
259
traversedModules : Set < ModuleNode > ,
255
260
boundaries : { boundary : ModuleNode ; acceptedVia : ModuleNode } [ ] ,
256
261
currentChain : ModuleNode [ ] = [ node ] ,
257
- ) : boolean /* hasDeadEnd */ {
262
+ ) : HasDeadEnd {
258
263
if ( traversedModules . has ( node ) ) {
259
264
return false
260
265
}
@@ -274,9 +279,8 @@ function propagateUpdate(
274
279
275
280
if ( node . isSelfAccepting ) {
276
281
boundaries . push ( { boundary : node , acceptedVia : node } )
277
- if ( isNodeWithinCircularImports ( node , currentChain ) ) {
278
- return true
279
- }
282
+ const result = isNodeWithinCircularImports ( node , currentChain )
283
+ if ( result ) return result
280
284
281
285
// additionally check for CSS importers, since a PostCSS plugin like
282
286
// Tailwind JIT may register any file as a dependency to a CSS file.
@@ -301,9 +305,8 @@ function propagateUpdate(
301
305
// so that they do get the fresh imported module when/if they are reloaded.
302
306
if ( node . acceptedHmrExports ) {
303
307
boundaries . push ( { boundary : node , acceptedVia : node } )
304
- if ( isNodeWithinCircularImports ( node , currentChain ) ) {
305
- return true
306
- }
308
+ const result = isNodeWithinCircularImports ( node , currentChain )
309
+ if ( result ) return result
307
310
} else {
308
311
if ( ! node . importers . size ) {
309
312
return true
@@ -325,9 +328,8 @@ function propagateUpdate(
325
328
326
329
if ( importer . acceptedHmrDeps . has ( node ) ) {
327
330
boundaries . push ( { boundary : importer , acceptedVia : node } )
328
- if ( isNodeWithinCircularImports ( importer , subChain ) ) {
329
- return true
330
- }
331
+ const result = isNodeWithinCircularImports ( importer , subChain )
332
+ if ( result ) return result
331
333
continue
332
334
}
333
335
@@ -364,7 +366,7 @@ function isNodeWithinCircularImports(
364
366
node : ModuleNode ,
365
367
nodeChain : ModuleNode [ ] ,
366
368
currentChain : ModuleNode [ ] = [ node ] ,
367
- ) {
369
+ ) : HasDeadEnd {
368
370
// To help visualize how each parameters work, imagine this import graph:
369
371
//
370
372
// A -> B -> C -> ACCEPTED -> D -> E -> NODE
@@ -405,19 +407,17 @@ function isNodeWithinCircularImports(
405
407
importChain . map ( ( m ) => colors . dim ( m . url ) ) . join ( ' -> ' ) ,
406
408
)
407
409
}
408
- return true
410
+ return 'circular imports'
409
411
}
410
412
411
413
// Continue recursively
412
- if (
413
- ! currentChain . includes ( importer ) &&
414
- isNodeWithinCircularImports (
414
+ if ( ! currentChain . includes ( importer ) ) {
415
+ const result = isNodeWithinCircularImports (
415
416
importer ,
416
417
nodeChain ,
417
418
currentChain . concat ( importer ) ,
418
419
)
419
- ) {
420
- return true
420
+ if ( result ) return result
421
421
}
422
422
}
423
423
return false
0 commit comments