@@ -4,8 +4,13 @@ import { Plugin } from '../plugin'
4
4
import MagicString from 'magic-string'
5
5
import { ImportSpecifier , init , parse as parseImports } from 'es-module-lexer'
6
6
import { OutputChunk } from 'rollup'
7
- import { chunkToEmittedCssFileMap , removedPureCssFilesCache } from './css'
7
+ import {
8
+ chunkToEmittedCssFileMap ,
9
+ isCSSRequest ,
10
+ removedPureCssFilesCache
11
+ } from './css'
8
12
import { transformImportGlob } from '../importGlob'
13
+ import { bareImportRE } from '../utils'
9
14
10
15
/**
11
16
* A flag for injected helpers. This flag will be set to `false` if the output
@@ -116,7 +121,7 @@ export function buildImportAnalysisPlugin(config: ResolvedConfig): Plugin {
116
121
let imports : readonly ImportSpecifier [ ] = [ ]
117
122
try {
118
123
imports = parseImports ( source ) [ 0 ]
119
- } catch ( e ) {
124
+ } catch ( e : any ) {
120
125
this . error ( e , e . idx )
121
126
}
122
127
@@ -133,15 +138,15 @@ export function buildImportAnalysisPlugin(config: ResolvedConfig): Plugin {
133
138
s : start ,
134
139
e : end ,
135
140
ss : expStart ,
141
+ n : specifier ,
136
142
d : dynamicIndex
137
143
} = imports [ index ]
138
144
139
- const isGlob =
145
+ // import.meta.glob
146
+ if (
140
147
source . slice ( start , end ) === 'import.meta' &&
141
148
source . slice ( end , end + 5 ) === '.glob'
142
-
143
- // import.meta.glob
144
- if ( isGlob ) {
149
+ ) {
145
150
const { importsString, exp, endIndex, isEager } =
146
151
await transformImportGlob (
147
152
source ,
@@ -167,6 +172,21 @@ export function buildImportAnalysisPlugin(config: ResolvedConfig): Plugin {
167
172
const replacement = `${ preloadMethod } (() => ${ original } ,${ isModernFlag } ?"${ preloadMarker } ":void 0)`
168
173
str ( ) . overwrite ( dynamicIndex , dynamicEnd , replacement )
169
174
}
175
+
176
+ // Differentiate CSS imports that use the default export from those that
177
+ // do not by injecting a ?used query - this allows us to avoid including
178
+ // the CSS string when unnecessary (esbuild has trouble treeshaking
179
+ // them)
180
+ if (
181
+ specifier &&
182
+ isCSSRequest ( specifier ) &&
183
+ source . slice ( expStart , start ) . includes ( 'from' ) &&
184
+ // edge case for package names ending with .css (e.g normalize.css)
185
+ ! ( bareImportRE . test ( specifier ) && ! specifier . includes ( '/' ) )
186
+ ) {
187
+ const url = specifier . replace ( / \? | $ / , ( m ) => `?used${ m ? '&' : '' } ` )
188
+ str ( ) . overwrite ( start , end , dynamicIndex > - 1 ? `'${ url } '` : url )
189
+ }
170
190
}
171
191
172
192
if (
@@ -225,7 +245,7 @@ export function buildImportAnalysisPlugin(config: ResolvedConfig): Plugin {
225
245
let imports : ImportSpecifier [ ]
226
246
try {
227
247
imports = parseImports ( code ) [ 0 ] . filter ( ( i ) => i . d > - 1 )
228
- } catch ( e ) {
248
+ } catch ( e : any ) {
229
249
this . error ( e , e . idx )
230
250
}
231
251
0 commit comments