@@ -293,7 +293,7 @@ async function prepareRolldownScanner(
293
293
294
294
const plugins = await asyncFlatten ( arraify ( pluginsFromConfig ) )
295
295
296
- plugins . push ( rolldownScanPlugin ( environment , deps , missing , entries ) )
296
+ plugins . push ( ... rolldownScanPlugin ( environment , deps , missing , entries ) )
297
297
298
298
async function build ( ) {
299
299
await scan ( {
@@ -350,7 +350,7 @@ function rolldownScanPlugin(
350
350
depImports : Record < string , string > ,
351
351
missing : Record < string , string > ,
352
352
entries : string [ ] ,
353
- ) : Plugin {
353
+ ) : Plugin [ ] {
354
354
const seen = new Map < string , string | undefined > ( )
355
355
async function resolveId (
356
356
id : string ,
@@ -533,182 +533,203 @@ function rolldownScanPlugin(
533
533
534
534
const ASSET_TYPE_RE = new RegExp ( `\\.(${ KNOWN_ASSET_TYPES . join ( '|' ) } )$` )
535
535
536
- return {
537
- name : 'vite:dep-scan' ,
538
- async resolveId ( id , importer ) {
539
- // external urls
540
- if ( externalRE . test ( id ) ) {
541
- return {
542
- id,
543
- external : true ,
536
+ return [
537
+ {
538
+ name : 'vite:dep-scan:resolve' ,
539
+ async resolveId ( id , importer ) {
540
+ // external urls
541
+ if ( externalRE . test ( id ) ) {
542
+ return {
543
+ id,
544
+ external : true ,
545
+ }
544
546
}
545
- }
546
547
547
- // data urls
548
- if ( dataUrlRE . test ( id ) ) {
549
- return {
550
- id,
551
- external : true ,
548
+ // data urls
549
+ if ( dataUrlRE . test ( id ) ) {
550
+ return {
551
+ id,
552
+ external : true ,
553
+ }
552
554
}
553
- }
554
-
555
- // local scripts (`<script>` in Svelte and `<script setup>` in Vue)
556
- if ( virtualModuleRE . test ( id ) ) {
557
- return id
558
- }
559
555
560
- // Make sure virtual module importer can be resolve
561
- importer =
562
- importer && virtualModuleRE . test ( importer )
563
- ? importer . replace ( virtualModulePrefix , '' )
564
- : importer
565
-
566
- // html types: extract script contents -----------------------------------
567
- if ( htmlTypesRE . test ( id ) ) {
568
- const resolved = await resolve ( id , importer )
569
- if ( ! resolved ) return
570
- // It is possible for the scanner to scan html types in node_modules.
571
- // If we can optimize this html type, skip it so it's handled by the
572
- // bare import resolve, and recorded as optimization dep.
573
- if (
574
- isInNodeModules ( resolved ) &&
575
- isOptimizable ( resolved , optimizeDepsOptions )
576
- )
577
- return
578
- return resolved
579
- }
580
-
581
- // bare imports: record and externalize ----------------------------------
582
- // avoid matching windows volume
583
- if ( / ^ [ \w @ ] [ ^ : ] / . test ( id ) ) {
584
- if ( moduleListContains ( exclude , id ) ) {
585
- return externalUnlessEntry ( { path : id } )
556
+ // local scripts (`<script>` in Svelte and `<script setup>` in Vue)
557
+ if ( virtualModuleRE . test ( id ) ) {
558
+ return id
586
559
}
587
- if ( depImports [ id ] ) {
588
- return externalUnlessEntry ( { path : id } )
560
+
561
+ // Make sure virtual module importer can be resolve
562
+ importer =
563
+ importer && virtualModuleRE . test ( importer )
564
+ ? importer . replace ( virtualModulePrefix , '' )
565
+ : importer
566
+
567
+ // html types: extract script contents -----------------------------------
568
+ if ( htmlTypesRE . test ( id ) ) {
569
+ const resolved = await resolve ( id , importer )
570
+ if ( ! resolved ) return
571
+ // It is possible for the scanner to scan html types in node_modules.
572
+ // If we can optimize this html type, skip it so it's handled by the
573
+ // bare import resolve, and recorded as optimization dep.
574
+ if (
575
+ isInNodeModules ( resolved ) &&
576
+ isOptimizable ( resolved , optimizeDepsOptions )
577
+ )
578
+ return
579
+ return resolved
589
580
}
590
- const resolved = await resolve ( id , importer , {
591
- custom : {
592
- depScan : importer ? { loader : scripts [ importer ] ?. loader } : { } ,
593
- } ,
594
- } )
595
- if ( resolved ) {
596
- if ( shouldExternalizeDep ( resolved , id ) ) {
581
+
582
+ // bare imports: record and externalize ----------------------------------
583
+ // avoid matching windows volume
584
+ if ( / ^ [ \w @ ] [ ^ : ] / . test ( id ) ) {
585
+ if ( moduleListContains ( exclude , id ) ) {
597
586
return externalUnlessEntry ( { path : id } )
598
587
}
599
- if ( isInNodeModules ( resolved ) || include ?. includes ( id ) ) {
600
- // dependency or forced included, externalize and stop crawling
601
- if ( isOptimizable ( resolved , optimizeDepsOptions ) ) {
602
- depImports [ id ] = resolved
603
- }
588
+ if ( depImports [ id ] ) {
604
589
return externalUnlessEntry ( { path : id } )
605
- } else if ( isScannable ( resolved , optimizeDepsOptions . extensions ) ) {
606
- // linked package, keep crawling
607
- return path . resolve ( resolved )
590
+ }
591
+ const resolved = await resolve ( id , importer , {
592
+ custom : {
593
+ depScan : importer ? { loader : scripts [ importer ] ?. loader } : { } ,
594
+ } ,
595
+ } )
596
+ if ( resolved ) {
597
+ if ( shouldExternalizeDep ( resolved , id ) ) {
598
+ return externalUnlessEntry ( { path : id } )
599
+ }
600
+ if ( isInNodeModules ( resolved ) || include ?. includes ( id ) ) {
601
+ // dependency or forced included, externalize and stop crawling
602
+ if ( isOptimizable ( resolved , optimizeDepsOptions ) ) {
603
+ depImports [ id ] = resolved
604
+ }
605
+ return externalUnlessEntry ( { path : id } )
606
+ } else if ( isScannable ( resolved , optimizeDepsOptions . extensions ) ) {
607
+ // linked package, keep crawling
608
+ return path . resolve ( resolved )
609
+ } else {
610
+ return externalUnlessEntry ( { path : id } )
611
+ }
608
612
} else {
609
- return externalUnlessEntry ( { path : id } )
613
+ missing [ id ] = normalizePath ( importer ! )
610
614
}
611
- } else {
612
- missing [ id ] = normalizePath ( importer ! )
613
- }
614
- }
615
-
616
- // Externalized file types -----------------------------------------------
617
- // these are done on raw ids using esbuild's native regex filter so it
618
- // should be faster than doing it in the catch-all via js
619
- // they are done after the bare import resolve because a package name
620
- // may end with these extensions
621
-
622
- // css
623
- if ( CSS_LANGS_RE . test ( id ) ) {
624
- return externalUnlessEntry ( { path : id } )
625
- }
626
-
627
- // json & wasm
628
- if ( / \. (?: j s o n | j s o n 5 | w a s m ) $ / . test ( id ) ) {
629
- return externalUnlessEntry ( { path : id } )
630
- }
631
-
632
- // known asset types
633
- if ( ASSET_TYPE_RE . test ( id ) ) {
634
- return externalUnlessEntry ( { path : id } )
635
- }
636
-
637
- // known vite query types: ?worker, ?raw
638
- if ( SPECIAL_QUERY_RE . test ( id ) ) {
639
- return {
640
- id,
641
- external : true ,
642
615
}
643
- }
644
616
645
- // catch all -------------------------------------------------------------
617
+ // Externalized file types -----------------------------------------------
618
+ // these are done on raw ids using esbuild's native regex filter so it
619
+ // should be faster than doing it in the catch-all via js
620
+ // they are done after the bare import resolve because a package name
621
+ // may end with these extensions
646
622
647
- // use vite resolver to support urls and omitted extensions
648
- const resolved = await resolve ( id , importer , {
649
- custom : {
650
- depScan : importer ? { loader : scripts [ importer ] ?. loader } : { } ,
651
- } ,
652
- } )
653
- if ( resolved ) {
654
- if (
655
- shouldExternalizeDep ( resolved , id ) ||
656
- ! isScannable ( resolved , optimizeDepsOptions . extensions )
657
- ) {
623
+ // css
624
+ if ( CSS_LANGS_RE . test ( id ) ) {
658
625
return externalUnlessEntry ( { path : id } )
659
626
}
660
- return path . resolve ( cleanUrl ( resolved ) )
661
- }
662
627
663
- // resolve failed... probably unsupported type
664
- return externalUnlessEntry ( { path : id } )
665
- } ,
666
- async load ( id ) {
667
- if ( virtualModuleRE . test ( id ) ) {
668
- const script = scripts [ id . replace ( virtualModulePrefix , '' ) ]
669
- return {
670
- code : script . contents ,
671
- moduleType : script . loader ,
628
+ // json & wasm
629
+ if ( / \. (?: j s o n | j s o n 5 | w a s m ) $ / . test ( id ) ) {
630
+ return externalUnlessEntry ( { path : id } )
672
631
}
673
- }
674
632
675
- // extract scripts inside HTML-like files and treat it as a js module
676
- if ( htmlTypesRE . test ( id ) ) {
677
- return {
678
- code : await htmlTypeOnLoadCallback ( id ) ,
679
- moduleType : 'js' ,
633
+ // known asset types
634
+ if ( ASSET_TYPE_RE . test ( id ) ) {
635
+ return externalUnlessEntry ( { path : id } )
680
636
}
681
- }
682
637
683
- // for jsx/tsx, we need to access the content and check for
684
- // presence of import.meta.glob, since it results in import relationships
685
- // but isn't crawled by esbuild.
686
- if ( JS_TYPES_RE . test ( id ) ) {
687
- let ext = path . extname ( id ) . slice ( 1 )
688
- if ( ext === 'mjs' ) ext = 'js'
689
-
690
- const esbuildConfig = environment . config . esbuild
691
- let contents = await fsp . readFile ( id , 'utf-8' )
692
- if ( ext . endsWith ( 'x' ) && esbuildConfig && esbuildConfig . jsxInject ) {
693
- contents = esbuildConfig . jsxInject + `\n` + contents
638
+ // known vite query types: ?worker, ?raw
639
+ if ( SPECIAL_QUERY_RE . test ( id ) ) {
640
+ return {
641
+ id,
642
+ external : true ,
643
+ }
694
644
}
695
645
696
- const loader = ext as 'js' | 'ts' | 'jsx' | 'tsx'
646
+ // catch all -------------------------------------------------------------
697
647
698
- if ( contents . includes ( 'import.meta.glob' ) ) {
699
- return {
700
- moduleType : 'js' ,
701
- code : await doTransformGlobImport ( contents , id , loader ) ,
648
+ // use vite resolver to support urls and omitted extensions
649
+ const resolved = await resolve ( id , importer , {
650
+ custom : {
651
+ depScan : importer ? { loader : scripts [ importer ] ?. loader } : { } ,
652
+ } ,
653
+ } )
654
+ if ( resolved ) {
655
+ if (
656
+ shouldExternalizeDep ( resolved , id ) ||
657
+ ! isScannable ( resolved , optimizeDepsOptions . extensions )
658
+ ) {
659
+ return externalUnlessEntry ( { path : id } )
702
660
}
661
+ return path . resolve ( cleanUrl ( resolved ) )
703
662
}
704
663
705
- return {
706
- moduleType : loader ,
707
- code : contents ,
708
- }
709
- }
664
+ // resolve failed... probably unsupported type
665
+ return externalUnlessEntry ( { path : id } )
666
+ } ,
710
667
} ,
711
- }
668
+ {
669
+ name : 'vite:dep-scan:load:html' ,
670
+ load : {
671
+ filter : { id : [ virtualModuleRE , htmlTypesRE ] } ,
672
+ async handler ( id ) {
673
+ if ( virtualModuleRE . test ( id ) ) {
674
+ const script = scripts [ id . replace ( virtualModulePrefix , '' ) ]
675
+ return {
676
+ code : script . contents ,
677
+ moduleType : script . loader ,
678
+ }
679
+ }
680
+
681
+ // extract scripts inside HTML-like files and treat it as a js module
682
+ if ( htmlTypesRE . test ( id ) ) {
683
+ return {
684
+ code : await htmlTypeOnLoadCallback ( id ) ,
685
+ moduleType : 'js' ,
686
+ }
687
+ }
688
+ } ,
689
+ } ,
690
+ } ,
691
+ // for jsx/tsx, we need to access the content and check for
692
+ // presence of import.meta.glob, since it results in import relationships
693
+ // but isn't crawled by esbuild.
694
+ ...( environment . config . esbuild && environment . config . esbuild . jsxInject
695
+ ? [
696
+ {
697
+ name : 'vite:dep-scan:transform:jsx-inject' ,
698
+ transform : {
699
+ filter : {
700
+ id : / \. [ j t ] s x $ / ,
701
+ } ,
702
+ handler ( code ) {
703
+ const esbuildConfig = environment . config . esbuild
704
+ if ( esbuildConfig && esbuildConfig . jsxInject ) {
705
+ code = esbuildConfig . jsxInject + `\n` + code
706
+ }
707
+ return code
708
+ } ,
709
+ } ,
710
+ } satisfies Plugin ,
711
+ ]
712
+ : [ ] ) ,
713
+ {
714
+ name : 'vite:dep-scan:transform:js-glob' ,
715
+ transform : {
716
+ filter : {
717
+ code : 'import.meta.glob' ,
718
+ } ,
719
+ async handler ( code , id ) {
720
+ if ( JS_TYPES_RE . test ( id ) ) {
721
+ let ext = path . extname ( id ) . slice ( 1 )
722
+ if ( ext === 'mjs' ) ext = 'js'
723
+ const loader = ext as 'js' | 'ts' | 'jsx' | 'tsx'
724
+ return {
725
+ moduleType : 'js' ,
726
+ code : await doTransformGlobImport ( code , id , loader ) ,
727
+ }
728
+ }
729
+ } ,
730
+ } ,
731
+ } ,
732
+ ]
712
733
}
713
734
714
735
/**
0 commit comments