@@ -31,8 +31,9 @@ interface ManifestAssetResolvers {
3131 getStylesheetAsset : ( cssFile : string ) => RouterManagedTag
3232}
3333
34- type DedupePreloadRoute = {
34+ type DedupeRoute = {
3535 preloads ?: Array < ManifestAssetLink >
36+ assets ?: Array < RouterManagedTag >
3637 children ?: Array < string >
3738}
3839
@@ -158,7 +159,7 @@ export function buildStartManifest(options: {
158159 assetResolvers,
159160 } )
160161
161- dedupeNestedRoutePreloads ( routes [ rootRouteId ] ! , routes )
162+ dedupeNestedRouteManifestEntries ( rootRouteId , routes [ rootRouteId ] ! , routes )
162163
163164 // Prune routes with no assets or preloads from the manifest
164165 for ( const routeId of Object . keys ( routes ) ) {
@@ -418,6 +419,20 @@ export function createChunkCssAssetCollector(options: {
418419 const assetsByChunk = new Map < Rollup . OutputChunk , Array < RouterManagedTag > > ( )
419420 const stateByChunk = new Map < Rollup . OutputChunk , number > ( )
420421
422+ const appendAsset = (
423+ assets : Array < RouterManagedTag > ,
424+ seenAssets : Set < string > ,
425+ asset : RouterManagedTag ,
426+ ) => {
427+ const identity = getAssetIdentity ( asset )
428+ if ( seenAssets . has ( identity ) ) {
429+ return
430+ }
431+
432+ seenAssets . add ( identity )
433+ assets . push ( asset )
434+ }
435+
421436 const getChunkCssAssets = (
422437 chunk : Rollup . OutputChunk ,
423438 ) : Array < RouterManagedTag > => {
@@ -432,9 +447,10 @@ export function createChunkCssAssetCollector(options: {
432447 stateByChunk . set ( chunk , VISITING_CHUNK )
433448
434449 const assets : Array < RouterManagedTag > = [ ]
450+ const seenAssets = new Set < string > ( )
435451
436452 for ( const cssFile of chunk . viteMetadata ?. importedCss ?? [ ] ) {
437- assets . push ( options . getStylesheetAsset ( cssFile ) )
453+ appendAsset ( assets , seenAssets , options . getStylesheetAsset ( cssFile ) )
438454 }
439455
440456 for ( let i = 0 ; i < chunk . imports . length ; i ++ ) {
@@ -445,7 +461,7 @@ export function createChunkCssAssetCollector(options: {
445461
446462 const importedAssets = getChunkCssAssets ( importedChunk )
447463 for ( let j = 0 ; j < importedAssets . length ; j ++ ) {
448- assets . push ( importedAssets [ j ] ! )
464+ appendAsset ( assets , seenAssets , importedAssets [ j ] ! )
449465 }
450466 }
451467
@@ -510,12 +526,15 @@ export function buildRouteManifestRoutes(options: {
510526 return routes
511527}
512528
513- export function dedupeNestedRoutePreloads (
514- route : DedupePreloadRoute ,
515- routesById : Record < string , DedupePreloadRoute > ,
529+ function dedupeNestedRouteManifestEntries (
530+ routeId : string ,
531+ route : DedupeRoute ,
532+ routesById : Record < string , DedupeRoute > ,
516533 seenPreloads = new Set < string > ( ) ,
534+ seenAssets = new Set < string > ( ) ,
517535) {
518536 let routePreloads = route . preloads
537+ let routeAssets = route . assets
519538
520539 if ( routePreloads && routePreloads . length > 0 ) {
521540 let dedupedPreloads : Array < ManifestAssetLink > | undefined
@@ -544,12 +563,49 @@ export function dedupeNestedRoutePreloads(
544563 }
545564 }
546565
566+ if ( routeAssets && routeAssets . length > 0 ) {
567+ let dedupedAssets : Array < RouterManagedTag > | undefined
568+
569+ for ( let i = 0 ; i < routeAssets . length ; i ++ ) {
570+ const asset = routeAssets [ i ] !
571+ const identity = getAssetIdentity ( asset )
572+
573+ if ( seenAssets . has ( identity ) ) {
574+ if ( dedupedAssets === undefined ) {
575+ dedupedAssets = routeAssets . slice ( 0 , i )
576+ }
577+ continue
578+ }
579+
580+ seenAssets . add ( identity )
581+
582+ if ( dedupedAssets ) {
583+ dedupedAssets . push ( asset )
584+ }
585+ }
586+
587+ if ( dedupedAssets ) {
588+ routeAssets = dedupedAssets
589+ route . assets = dedupedAssets
590+ }
591+ }
592+
547593 if ( route . children ) {
548594 for ( const childRouteId of route . children ) {
549- dedupeNestedRoutePreloads (
550- routesById [ childRouteId ] ! ,
595+ const childRoute = routesById [ childRouteId ]
596+
597+ if ( ! childRoute ) {
598+ throw new Error (
599+ `Route tree references child route ${ childRouteId } from ${ routeId } , but no route entry was found` ,
600+ )
601+ }
602+
603+ dedupeNestedRouteManifestEntries (
604+ childRouteId ,
605+ childRoute ,
551606 routesById ,
552607 seenPreloads ,
608+ seenAssets ,
553609 )
554610 }
555611 }
@@ -559,4 +615,10 @@ export function dedupeNestedRoutePreloads(
559615 seenPreloads . delete ( resolveManifestAssetLink ( routePreloads [ i ] ! ) . href )
560616 }
561617 }
618+
619+ if ( routeAssets ) {
620+ for ( let i = routeAssets . length - 1 ; i >= 0 ; i -- ) {
621+ seenAssets . delete ( getAssetIdentity ( routeAssets [ i ] ! ) )
622+ }
623+ }
562624}
0 commit comments