1
- import type { RuntimeMode } from '../@types/astro.js' ;
2
1
import type { ModuleLoader } from '../core/module-loader/index.js' ;
3
2
import { viteID } from '../core/util.js' ;
4
3
import { isBuildableCSSRequest } from './util.js' ;
@@ -13,37 +12,48 @@ interface ImportedStyle {
13
12
/** Given a filePath URL, crawl Vite’s module graph to find all style imports. */
14
13
export async function getStylesForURL (
15
14
filePath : URL ,
16
- loader : ModuleLoader ,
17
- mode : RuntimeMode
15
+ loader : ModuleLoader
18
16
) : Promise < { urls : Set < string > ; styles : ImportedStyle [ ] } > {
19
17
const importedCssUrls = new Set < string > ( ) ;
20
18
// Map of url to injected style object. Use a `url` key to deduplicate styles
21
19
const importedStylesMap = new Map < string , ImportedStyle > ( ) ;
22
20
23
21
for await ( const importedModule of crawlGraph ( loader , viteID ( filePath ) , true ) ) {
24
22
if ( isBuildableCSSRequest ( importedModule . url ) ) {
25
- let ssrModule : Record < string , any > ;
26
- try {
27
- // The SSR module is possibly not loaded. Load it if it's null.
28
- ssrModule = importedModule . ssrModule ?? ( await loader . import ( importedModule . url ) ) ;
29
- } catch {
30
- // The module may not be inline-able, e.g. SCSS partials. Skip it as it may already
31
- // be inlined into other modules if it happens to be in the graph.
32
- continue ;
23
+ // In dev, we inline all styles if possible
24
+ let css = '' ;
25
+ // If this is a plain CSS module, the default export should be a string
26
+ if ( typeof importedModule . ssrModule ?. default === 'string' ) {
27
+ css = importedModule . ssrModule . default ;
33
28
}
34
- if (
35
- mode === 'development' && // only inline in development
36
- typeof ssrModule ?. default === 'string' // ignore JS module styles
37
- ) {
38
- importedStylesMap . set ( importedModule . url , {
39
- id : importedModule . id ?? importedModule . url ,
40
- url : importedModule . url ,
41
- content : ssrModule . default ,
42
- } ) ;
43
- } else {
44
- // NOTE: We use the `url` property here. `id` would break Windows.
45
- importedCssUrls . add ( importedModule . url ) ;
29
+ // Else try to load it
30
+ else {
31
+ const url = new URL ( importedModule . url , 'http://localhost' ) ;
32
+ // Mark url with ?inline so Vite will return the CSS as plain string, even for CSS modules
33
+ url . searchParams . set ( 'inline' , '' ) ;
34
+ const modId = `${ decodeURI ( url . pathname ) } ${ url . search } ` ;
35
+
36
+ try {
37
+ // The SSR module is possibly not loaded. Load it if it's null.
38
+ const ssrModule = await loader . import ( modId ) ;
39
+ css = ssrModule . default ;
40
+ } catch {
41
+ // Some CSS modules, e.g. from Vue files, may not work with the ?inline query.
42
+ // If so, we fallback to a url instead
43
+ if ( modId . includes ( '.module.' ) ) {
44
+ importedCssUrls . add ( importedModule . url ) ;
45
+ }
46
+ // The module may not be inline-able, e.g. SCSS partials. Skip it as it may already
47
+ // be inlined into other modules if it happens to be in the graph.
48
+ continue ;
49
+ }
46
50
}
51
+
52
+ importedStylesMap . set ( importedModule . url , {
53
+ id : importedModule . id ?? importedModule . url ,
54
+ url : importedModule . url ,
55
+ content : css ,
56
+ } ) ;
47
57
}
48
58
}
49
59
0 commit comments