@@ -374,20 +374,20 @@ export function cssPlugin(config: ResolvedConfig): Plugin {
374
374
const resolveUrl = ( url : string , importer ?: string ) =>
375
375
idResolver ( environment , url , importer )
376
376
377
- const urlReplacer : CssUrlReplacer = async ( url , importer ) => {
377
+ const urlResolver : CssUrlResolver = async ( url , importer ) => {
378
378
const decodedUrl = decodeURI ( url )
379
379
if ( checkPublicFile ( decodedUrl , config ) ) {
380
380
if ( encodePublicUrlsInCSS ( config ) ) {
381
- return publicFileToBuiltUrl ( decodedUrl , config )
381
+ return [ publicFileToBuiltUrl ( decodedUrl , config ) , undefined ]
382
382
} else {
383
- return joinUrlSegments ( config . base , decodedUrl )
383
+ return [ joinUrlSegments ( config . base , decodedUrl ) , undefined ]
384
384
}
385
385
}
386
386
const [ id , fragment ] = decodedUrl . split ( '#' )
387
387
let resolved = await resolveUrl ( id , importer )
388
388
if ( resolved ) {
389
389
if ( fragment ) resolved += '#' + fragment
390
- return fileToUrl ( this , resolved )
390
+ return [ await fileToUrl ( this , resolved ) , resolved ]
391
391
}
392
392
if ( config . command === 'build' ) {
393
393
const isExternal = config . build . rollupOptions . external
@@ -406,7 +406,7 @@ export function cssPlugin(config: ResolvedConfig): Plugin {
406
406
)
407
407
}
408
408
}
409
- return url
409
+ return [ url , undefined ]
410
410
}
411
411
412
412
const {
@@ -419,7 +419,7 @@ export function cssPlugin(config: ResolvedConfig): Plugin {
419
419
id ,
420
420
raw ,
421
421
preprocessorWorkerController ! ,
422
- urlReplacer ,
422
+ urlResolver ,
423
423
)
424
424
if ( modules ) {
425
425
moduleCache . set ( id , modules )
@@ -1059,17 +1059,20 @@ export function cssAnalysisPlugin(config: ResolvedConfig): Plugin {
1059
1059
// main import to hot update
1060
1060
const depModules = new Set < string | EnvironmentModuleNode > ( )
1061
1061
for ( const file of pluginImports ) {
1062
- depModules . add (
1063
- isCSSRequest ( file )
1064
- ? moduleGraph . createFileOnlyEntry ( file )
1065
- : await moduleGraph . ensureEntryFromUrl (
1066
- await fileToDevUrl (
1067
- this . environment ,
1068
- file ,
1069
- /* skipBase */ true ,
1070
- ) ,
1071
- ) ,
1072
- )
1062
+ if ( isCSSRequest ( file ) ) {
1063
+ depModules . add ( moduleGraph . createFileOnlyEntry ( file ) )
1064
+ } else {
1065
+ const url = await fileToDevUrl (
1066
+ this . environment ,
1067
+ file ,
1068
+ /* skipBase */ true ,
1069
+ )
1070
+ if ( url . startsWith ( 'data:' ) ) {
1071
+ depModules . add ( moduleGraph . createFileOnlyEntry ( file ) )
1072
+ } else {
1073
+ depModules . add ( await moduleGraph . ensureEntryFromUrl ( url ) )
1074
+ }
1075
+ }
1073
1076
}
1074
1077
moduleGraph . updateModuleInfo (
1075
1078
thisModule ,
@@ -1268,7 +1271,7 @@ async function compileCSS(
1268
1271
id : string ,
1269
1272
code : string ,
1270
1273
workerController : PreprocessorWorkerController ,
1271
- urlReplacer ?: CssUrlReplacer ,
1274
+ urlResolver ?: CssUrlResolver ,
1272
1275
) : Promise < {
1273
1276
code : string
1274
1277
map ?: SourceMapInput
@@ -1278,7 +1281,7 @@ async function compileCSS(
1278
1281
} > {
1279
1282
const { config } = environment
1280
1283
if ( config . css . transformer === 'lightningcss' ) {
1281
- return compileLightningCSS ( id , code , environment , urlReplacer )
1284
+ return compileLightningCSS ( id , code , environment , urlResolver )
1282
1285
}
1283
1286
1284
1287
const { modules : modulesOptions , devSourcemap } = config . css
@@ -1387,10 +1390,11 @@ async function compileCSS(
1387
1390
)
1388
1391
}
1389
1392
1390
- if ( urlReplacer ) {
1393
+ if ( urlResolver ) {
1391
1394
postcssPlugins . push (
1392
1395
UrlRewritePostcssPlugin ( {
1393
- replacer : urlReplacer ,
1396
+ resolver : urlResolver ,
1397
+ deps,
1394
1398
logger : environment . logger ,
1395
1399
} ) ,
1396
1400
)
@@ -1724,6 +1728,12 @@ async function resolvePostcssConfig(
1724
1728
return result
1725
1729
}
1726
1730
1731
+ type CssUrlResolver = (
1732
+ url : string ,
1733
+ importer ?: string ,
1734
+ ) =>
1735
+ | [ url : string , id : string | undefined ]
1736
+ | Promise < [ url : string , id : string | undefined ] >
1727
1737
type CssUrlReplacer = (
1728
1738
url : string ,
1729
1739
importer ?: string ,
@@ -1740,7 +1750,8 @@ export const importCssRE =
1740
1750
const cssImageSetRE = / (?< = i m a g e - s e t \( ) ( (?: [ \w - ] { 1 , 256 } \( [ ^ ) ] * \) | [ ^ ) ] ) * ) (? = \) ) /
1741
1751
1742
1752
const UrlRewritePostcssPlugin : PostCSS . PluginCreator < {
1743
- replacer : CssUrlReplacer
1753
+ resolver : CssUrlResolver
1754
+ deps : Set < string >
1744
1755
logger : Logger
1745
1756
} > = ( opts ) => {
1746
1757
if ( ! opts ) {
@@ -1764,8 +1775,13 @@ const UrlRewritePostcssPlugin: PostCSS.PluginCreator<{
1764
1775
const isCssUrl = cssUrlRE . test ( declaration . value )
1765
1776
const isCssImageSet = cssImageSetRE . test ( declaration . value )
1766
1777
if ( isCssUrl || isCssImageSet ) {
1767
- const replacerForDeclaration = ( rawUrl : string ) => {
1768
- return opts . replacer ( rawUrl , importer )
1778
+ const replacerForDeclaration = async ( rawUrl : string ) => {
1779
+ const [ newUrl , resolvedId ] = await opts . resolver ( rawUrl , importer )
1780
+ // only register inlined assets to avoid frequent full refresh (#18979)
1781
+ if ( newUrl . startsWith ( 'data:' ) && resolvedId ) {
1782
+ opts . deps . add ( resolvedId )
1783
+ }
1784
+ return newUrl
1769
1785
}
1770
1786
if ( isCssUrl && isCssImageSet ) {
1771
1787
promises . push (
@@ -3173,7 +3189,7 @@ async function compileLightningCSS(
3173
3189
id : string ,
3174
3190
src : string ,
3175
3191
environment : PartialEnvironment ,
3176
- urlReplacer ?: CssUrlReplacer ,
3192
+ urlResolver ?: CssUrlResolver ,
3177
3193
) : ReturnType < typeof compileCSS > {
3178
3194
const { config } = environment
3179
3195
const deps = new Set < string > ( )
@@ -3285,11 +3301,16 @@ async function compileLightningCSS(
3285
3301
let replaceUrl : string
3286
3302
if ( skipUrlReplacer ( dep . url ) ) {
3287
3303
replaceUrl = dep . url
3288
- } else if ( urlReplacer ) {
3289
- replaceUrl = await urlReplacer (
3304
+ } else if ( urlResolver ) {
3305
+ const [ newUrl , resolvedId ] = await urlResolver (
3290
3306
dep . url ,
3291
3307
dep . loc . filePath . replace ( NULL_BYTE_PLACEHOLDER , '\0' ) ,
3292
3308
)
3309
+ // only register inlined assets to avoid frequent full refresh (#18979)
3310
+ if ( newUrl . startsWith ( 'data:' ) && resolvedId ) {
3311
+ deps . add ( resolvedId )
3312
+ }
3313
+ replaceUrl = newUrl
3293
3314
} else {
3294
3315
replaceUrl = dep . url
3295
3316
}
0 commit comments