@@ -2,16 +2,9 @@ import path from "node:path";
22import { resolve } from "pathe" ;
33import type { DevEnvironment , EnvironmentModuleNode } from "vite" ;
44
5- const prepareTransformResult = async ( vite : DevEnvironment , module : EnvironmentModuleNode ) => {
6- if ( module . transformResult || ! module . id ) return ;
7-
8- await vite . transformRequest ( module . id ) . catch ( ( ) => { } ) ;
9- } ;
10-
115async function getViteModuleNode (
126 vite : DevEnvironment ,
137 file : string ,
14- ssr = false ,
158) {
169 let nodePath = file ;
1710 let node = vite . moduleGraph . getModuleById ( file ) ;
@@ -34,38 +27,36 @@ async function getViteModuleNode(
3427 node = vite . moduleGraph . getModuleById ( nodePath ) ;
3528 }
3629
37- if ( ! node ) return ;
38-
39- await prepareTransformResult ( vite , node ) ;
40-
4130 return node ;
4231}
4332
4433async function findModuleDependencies (
45- vite : DevEnvironment ,
46- module : EnvironmentModuleNode ,
47- ssr = false ,
34+ vite : DevEnvironment ,
35+ file : string ,
4836 deps : Set < EnvironmentModuleNode > ,
37+ crawledFiles = new Set < string > ( )
4938) {
50- async function add ( module : EnvironmentModuleNode ) {
51- if ( ! deps . has ( module ) ) {
52- deps . add ( module ) ;
53- await findModuleDependencies ( vite , module , ssr , deps ) ;
54- }
55- }
56-
57- async function addByUrl ( url : string , ssr : boolean ) {
58- const node = await getViteModuleNode ( vite , url , ssr ) ;
59-
60- if ( node ) await add ( node ) ;
61- }
39+ crawledFiles . add ( file ) ;
40+ const module = await getViteModuleNode ( vite , file ) ;
41+ if ( ! module ?. id || deps . has ( module ) ) return ;
6242
43+ deps . add ( module ) ;
44+
6345 if ( module . url . endsWith ( ".css" ) || module . url . includes ( "node_modules" ) ) return ;
6446
65- if ( ssr ) await prepareTransformResult ( vite , module ) ;
66-
67- for ( const mod of module . importedModules ) {
68- await addByUrl ( mod . url , ssr ) ;
47+ if ( ! module . transformResult ) {
48+ await vite . transformRequest ( module . id ) . catch ( ( ) => { } ) ;
49+ }
50+ if ( ! module . transformResult ?. deps ) return ;
51+
52+ // Relying on module.transformResult.deps instead of module.importedModules because:
53+ // transformResult properly separates imports into deps and dynamicDeps, importedModules doesn't
54+ // Style crawling has to skip dynamic imports as such modules load their styles themselves
55+ for ( const dep of module . transformResult . deps ) {
56+ if ( crawledFiles . has ( dep ) ) {
57+ continue ;
58+ }
59+ await findModuleDependencies ( vite , dep , deps , crawledFiles ) ;
6960 }
7061}
7162
@@ -79,61 +70,22 @@ const cssModulesRegExp = new RegExp(`\\.module${cssFileRegExp.source}`);
7970const isCssFile = ( file : string ) => cssFileRegExp . test ( file ) ;
8071export const isCssModulesFile = ( file : string ) => cssModulesRegExp . test ( file ) ;
8172
82- // https://github.com/remix-run/remix/blob/65326e39099f3b2285d83aecfe734ba35f668396/packages/remix-dev/vite/styles.ts#L29
83- const cssUrlParamsWithoutSideEffects = [ "url" , "inline" , "raw" , "inline-css" ] ;
84- export const isCssUrlWithoutSideEffects = ( url : string ) => {
85- const queryString = url . split ( "?" ) [ 1 ] ;
86-
87- if ( ! queryString ) {
88- return false ;
89- }
90-
91- const params = new URLSearchParams ( queryString ) ;
92- for ( const paramWithoutSideEffects of cssUrlParamsWithoutSideEffects ) {
93- if (
94- // Parameter is blank and not explicitly set, i.e. "?url", not "?url="
95- params . get ( paramWithoutSideEffects ) === "" &&
96- ! url . includes ( `?${ paramWithoutSideEffects } =` ) &&
97- ! url . includes ( `&${ paramWithoutSideEffects } =` )
98- ) {
99- return true ;
100- }
101- }
102-
103- return false ;
104- } ;
105-
106- async function findFilesDepedencies (
107- vite : DevEnvironment ,
108- files : Array < string > ,
109- ssr = false ,
110- deps = new Set < EnvironmentModuleNode > ( ) ,
111- ) {
112- for ( const file of files ) {
113- try {
114- const node = await getViteModuleNode ( vite , file , ssr ) ;
115- if ( node ) await findModuleDependencies ( vite , node , ssr , deps ) ;
116- } catch ( e ) {
117- console . error ( e ) ;
118- }
119- }
120-
121- return deps ;
122- }
123-
12473export async function findStylesInModuleGraph (
125- vite : DevEnvironment ,
74+ vite : DevEnvironment ,
12675 id : string ,
127- ssr = false ,
12876) {
12977 const absolute = path . resolve ( process . cwd ( ) , id ) ;
78+ const dependencies = new Set < EnvironmentModuleNode > ( ) ;
13079
131- const dependencies = await findFilesDepedencies ( vite , [ absolute ] , ssr ) ;
80+ try {
81+ await findModuleDependencies ( vite , absolute , dependencies ) ;
82+ } catch ( e ) {
83+ console . error ( e ) ;
84+ }
13285
13386 const styles : Record < string , any > = { } ;
134-
13587 for ( const dep of dependencies ) {
136- if ( isCssFile ( dep . url ) && dep . id ) {
88+ if ( dep . id && isCssFile ( dep . url ) ) {
13789 styles [ dep . id ] = dep . url ;
13890 }
13991 }
0 commit comments