@@ -14,6 +14,7 @@ import { readFile } from 'node:fs/promises';
14
14
import { builtinModules , isBuiltin } from 'node:module' ;
15
15
import { join } from 'node:path' ;
16
16
import type { Connect , DepOptimizationConfig , InlineConfig , ViteDevServer } from 'vite' ;
17
+ import type { ComponentStyleRecord } from '../../tools/vite/middlewares' ;
17
18
import {
18
19
ServerSsrMode ,
19
20
createAngularLocaleDataPlugin ,
@@ -175,7 +176,7 @@ export async function* serveWithVite(
175
176
explicitBrowser : [ ] ,
176
177
explicitServer : [ ] ,
177
178
} ;
178
- const usedComponentStyles = new Map < string , Set < string > > ( ) ;
179
+ const componentStyles = new Map < string , ComponentStyleRecord > ( ) ;
179
180
const templateUpdates = new Map < string , string > ( ) ;
180
181
181
182
// Add cleanup logic via a builder teardown.
@@ -232,11 +233,17 @@ export async function* serveWithVite(
232
233
assetFiles . set ( '/' + normalizePath ( outputPath ) , normalizePath ( file . inputPath ) ) ;
233
234
}
234
235
}
235
- // Clear stale template updates on a code rebuilds
236
+ // Clear stale template updates on code rebuilds
236
237
templateUpdates . clear ( ) ;
237
238
238
239
// Analyze result files for changes
239
- analyzeResultFiles ( normalizePath , htmlIndexPath , result . files , generatedFiles ) ;
240
+ analyzeResultFiles (
241
+ normalizePath ,
242
+ htmlIndexPath ,
243
+ result . files ,
244
+ generatedFiles ,
245
+ componentStyles ,
246
+ ) ;
240
247
break ;
241
248
case ResultKind . Incremental :
242
249
assert ( server , 'Builder must provide an initial full build before incremental results.' ) ;
@@ -321,7 +328,7 @@ export async function* serveWithVite(
321
328
server ,
322
329
serverOptions ,
323
330
context . logger ,
324
- usedComponentStyles ,
331
+ componentStyles ,
325
332
) ;
326
333
}
327
334
} else {
@@ -380,7 +387,7 @@ export async function* serveWithVite(
380
387
prebundleTransformer ,
381
388
target ,
382
389
isZonelessApp ( polyfills ) ,
383
- usedComponentStyles ,
390
+ componentStyles ,
384
391
templateUpdates ,
385
392
browserOptions . loader as EsbuildLoaderOption | undefined ,
386
393
extensions ?. middleware ,
@@ -406,7 +413,7 @@ export async function* serveWithVite(
406
413
key : 'r' ,
407
414
description : 'force reload browser' ,
408
415
action ( server ) {
409
- usedComponentStyles . clear ( ) ;
416
+ componentStyles . forEach ( ( record ) => record . used ?. clear ( ) ) ;
410
417
server . ws . send ( {
411
418
type : 'full-reload' ,
412
419
path : '*' ,
@@ -434,7 +441,7 @@ async function handleUpdate(
434
441
server : ViteDevServer ,
435
442
serverOptions : NormalizedDevServerOptions ,
436
443
logger : BuilderContext [ 'logger' ] ,
437
- usedComponentStyles : Map < string , Set < string | boolean > > ,
444
+ componentStyles : Map < string , ComponentStyleRecord > ,
438
445
) : Promise < void > {
439
446
const updatedFiles : string [ ] = [ ] ;
440
447
let destroyAngularServerAppCalled = false ;
@@ -478,15 +485,17 @@ async function handleUpdate(
478
485
// the existing search parameters when it performs an update and each one must be
479
486
// specified explicitly. Typically, there is only one each though as specific style files
480
487
// are not typically reused across components.
481
- const componentIds = usedComponentStyles . get ( filePath ) ;
482
- if ( componentIds ) {
483
- return Array . from ( componentIds ) . map ( ( id ) => {
484
- if ( id === true ) {
485
- // Shadow DOM components currently require a full reload.
486
- // Vite's CSS hot replacement does not support shadow root searching.
487
- requiresReload = true ;
488
- }
488
+ const record = componentStyles . get ( filePath ) ;
489
+ if ( record ) {
490
+ if ( record . reload ) {
491
+ // Shadow DOM components currently require a full reload.
492
+ // Vite's CSS hot replacement does not support shadow root searching.
493
+ requiresReload = true ;
494
+
495
+ return [ ] ;
496
+ }
489
497
498
+ return Array . from ( record . used ?? [ ] ) . map ( ( id ) => {
490
499
return {
491
500
type : 'css-update' as const ,
492
501
timestamp,
@@ -519,7 +528,7 @@ async function handleUpdate(
519
528
// Send reload command to clients
520
529
if ( serverOptions . liveReload ) {
521
530
// Clear used component tracking on full reload
522
- usedComponentStyles . clear ( ) ;
531
+ componentStyles . forEach ( ( record ) => record . used ?. clear ( ) ) ;
523
532
524
533
server . ws . send ( {
525
534
type : 'full-reload' ,
@@ -535,6 +544,7 @@ function analyzeResultFiles(
535
544
htmlIndexPath : string ,
536
545
resultFiles : Record < string , ResultFile > ,
537
546
generatedFiles : Map < string , OutputFileRecord > ,
547
+ componentStyles : Map < string , ComponentStyleRecord > ,
538
548
) {
539
549
const seen = new Set < string > ( [ '/index.html' ] ) ;
540
550
for ( const [ outputPath , file ] of Object . entries ( resultFiles ) ) {
@@ -589,12 +599,25 @@ function analyzeResultFiles(
589
599
type : file . type ,
590
600
servable,
591
601
} ) ;
602
+
603
+ // Record any external component styles
604
+ if ( filePath . endsWith ( '.css' ) && / ^ \/ [ a - f 0 - 9 ] { 64 } \. c s s $ / . test ( filePath ) ) {
605
+ const componentStyle = componentStyles . get ( filePath ) ;
606
+ if ( componentStyle ) {
607
+ componentStyle . rawContent = file . contents ;
608
+ } else {
609
+ componentStyles . set ( filePath , {
610
+ rawContent : file . contents ,
611
+ } ) ;
612
+ }
613
+ }
592
614
}
593
615
594
616
// Clear stale output files
595
617
for ( const file of generatedFiles . keys ( ) ) {
596
618
if ( ! seen . has ( file ) ) {
597
619
generatedFiles . delete ( file ) ;
620
+ componentStyles . delete ( file ) ;
598
621
}
599
622
}
600
623
}
@@ -609,7 +632,7 @@ export async function setupServer(
609
632
prebundleTransformer : JavaScriptTransformer ,
610
633
target : string [ ] ,
611
634
zoneless : boolean ,
612
- usedComponentStyles : Map < string , Set < string > > ,
635
+ componentStyles : Map < string , ComponentStyleRecord > ,
613
636
templateUpdates : Map < string , string > ,
614
637
prebundleLoaderExtensions : EsbuildLoaderOption | undefined ,
615
638
extensionMiddleware ?: Connect . NextHandleFunction [ ] ,
@@ -719,7 +742,7 @@ export async function setupServer(
719
742
assets,
720
743
indexHtmlTransformer,
721
744
extensionMiddleware,
722
- usedComponentStyles ,
745
+ componentStyles ,
723
746
templateUpdates,
724
747
ssrMode,
725
748
} ) ,
0 commit comments