@@ -36,6 +36,9 @@ export const assetUrlRE = /__VITE_ASSET__([\w$]+)__(?:\$_(.*?)__)?/g
36
36
37
37
const jsSourceMapRE = / \. [ c m ] ? j s \. m a p $ /
38
38
39
+ const noInlineRE = / [ ? & ] n o - i n l i n e \b /
40
+ const inlineRE = / [ ? & ] i n l i n e \b /
41
+
39
42
const assetCache = new WeakMap < Environment , Map < string , string > > ( )
40
43
41
44
/** a set of referenceId for entry CSS assets for each environment */
@@ -251,17 +254,26 @@ export async function fileToUrl(
251
254
) : Promise < string > {
252
255
const { environment } = pluginContext
253
256
if ( environment . config . command === 'serve' ) {
254
- return fileToDevUrl ( id , environment . getTopLevelConfig ( ) )
257
+ return fileToDevUrl ( environment , id )
255
258
} else {
256
259
return fileToBuiltUrl ( pluginContext , id )
257
260
}
258
261
}
259
262
260
- export function fileToDevUrl (
263
+ export async function fileToDevUrl (
264
+ environment : Environment ,
261
265
id : string ,
262
- config : ResolvedConfig ,
263
266
skipBase = false ,
264
- ) : string {
267
+ ) : Promise < string > {
268
+ const config = environment . getTopLevelConfig ( )
269
+
270
+ // If has inline query, unconditionally inline the asset
271
+ if ( inlineRE . test ( id ) ) {
272
+ const file = checkPublicFile ( id , config ) || cleanUrl ( id )
273
+ const content = await fsp . readFile ( file )
274
+ return assetToDataURL ( environment , file , content )
275
+ }
276
+
265
277
let rtn : string
266
278
if ( checkPublicFile ( id , config ) ) {
267
279
// in public dir during dev, keep the url as-is
@@ -335,8 +347,16 @@ async function fileToBuiltUrl(
335
347
) : Promise < string > {
336
348
const environment = pluginContext . environment
337
349
const topLevelConfig = environment . getTopLevelConfig ( )
338
- if ( ! skipPublicCheck && checkPublicFile ( id , topLevelConfig ) ) {
339
- return publicFileToBuiltUrl ( id , topLevelConfig )
350
+ if ( ! skipPublicCheck ) {
351
+ const publicFile = checkPublicFile ( id , topLevelConfig )
352
+ if ( publicFile ) {
353
+ if ( inlineRE . test ( id ) ) {
354
+ // If inline via query, re-assign the id so it can be read by the fs and inlined
355
+ id = publicFile
356
+ } else {
357
+ return publicFileToBuiltUrl ( id , topLevelConfig )
358
+ }
359
+ }
340
360
}
341
361
342
362
const cache = assetCache . get ( environment ) !
@@ -350,19 +370,7 @@ async function fileToBuiltUrl(
350
370
351
371
let url : string
352
372
if ( shouldInline ( pluginContext , file , id , content , forceInline ) ) {
353
- if ( environment . config . build . lib && isGitLfsPlaceholder ( content ) ) {
354
- environment . logger . warn (
355
- colors . yellow ( `Inlined file ${ id } was not downloaded via Git LFS` ) ,
356
- )
357
- }
358
-
359
- if ( file . endsWith ( '.svg' ) ) {
360
- url = svgToDataURL ( content )
361
- } else {
362
- const mimeType = mrmime . lookup ( file ) ?? 'application/octet-stream'
363
- // base64 inlined as a string
364
- url = `data:${ mimeType } ;base64,${ content . toString ( 'base64' ) } `
365
- }
373
+ url = assetToDataURL ( environment , file , content )
366
374
} else {
367
375
// emit as asset
368
376
const originalFileName = normalizePath (
@@ -414,6 +422,8 @@ const shouldInline = (
414
422
) : boolean => {
415
423
const environment = pluginContext . environment
416
424
const { assetsInlineLimit } = environment . config . build
425
+ if ( noInlineRE . test ( id ) ) return false
426
+ if ( inlineRE . test ( id ) ) return true
417
427
if ( environment . config . build . lib ) return true
418
428
if ( pluginContext . getModuleInfo ( id ) ?. isEntry ) return false
419
429
if ( forceInline !== undefined ) return forceInline
@@ -431,6 +441,26 @@ const shouldInline = (
431
441
return content . length < limit && ! isGitLfsPlaceholder ( content )
432
442
}
433
443
444
+ function assetToDataURL (
445
+ environment : Environment ,
446
+ file : string ,
447
+ content : Buffer ,
448
+ ) {
449
+ if ( environment . config . build . lib && isGitLfsPlaceholder ( content ) ) {
450
+ environment . logger . warn (
451
+ colors . yellow ( `Inlined file ${ file } was not downloaded via Git LFS` ) ,
452
+ )
453
+ }
454
+
455
+ if ( file . endsWith ( '.svg' ) ) {
456
+ return svgToDataURL ( content )
457
+ } else {
458
+ const mimeType = mrmime . lookup ( file ) ?? 'application/octet-stream'
459
+ // base64 inlined as a string
460
+ return `data:${ mimeType } ;base64,${ content . toString ( 'base64' ) } `
461
+ }
462
+ }
463
+
434
464
const nestedQuotesRE = / " [ ^ " ' ] * ' [ ^ " ] * " | ' [ ^ ' " ] * " [ ^ ' ] * ' /
435
465
436
466
// Inspired by https://github.com/iconify/iconify/blob/main/packages/utils/src/svg/url.ts
0 commit comments