@@ -5,9 +5,7 @@ import { Buffer } from 'node:buffer'
5
5
import * as mrmime from 'mrmime'
6
6
import type {
7
7
NormalizedOutputOptions ,
8
- OutputOptions ,
9
8
PluginContext ,
10
- PreRenderedAsset ,
11
9
RenderedChunk
12
10
} from 'rollup'
13
11
import MagicString from 'magic-string'
@@ -29,10 +27,15 @@ const urlRE = /(\?|&)url(?:&|$)/
29
27
const assetCache = new WeakMap < ResolvedConfig , Map < string , string > > ( )
30
28
31
29
// chunk.name is the basename for the asset ignoring the directory structure
32
- // For the manifest, we need to preserve the original file path
30
+ // For the manifest, we need to preserve the original file path and isEntry
31
+ // for CSS assets. We keep a map from referenceId to this information.
32
+ export interface GeneratedAssetMeta {
33
+ originalName : string
34
+ isEntry ?: boolean
35
+ }
33
36
export const generatedAssets = new WeakMap <
34
37
ResolvedConfig ,
35
- Map < string , { originalName : string } >
38
+ Map < string , GeneratedAssetMeta >
36
39
> ( )
37
40
38
41
// add own dictionary entry by directly assigning mrmime
@@ -248,120 +251,6 @@ export function getPublicAssetFilename(
248
251
return publicAssetUrlCache . get ( config ) ?. get ( hash )
249
252
}
250
253
251
- export function resolveAssetFileNames (
252
- config : ResolvedConfig
253
- ) : string | ( ( chunkInfo : PreRenderedAsset ) => string ) {
254
- const output = config . build ?. rollupOptions ?. output
255
- const defaultAssetFileNames = path . posix . join (
256
- config . build . assetsDir ,
257
- '[name].[hash][extname]'
258
- )
259
- // Steps to determine which assetFileNames will be actually used.
260
- // First, if output is an object or string, use assetFileNames in it.
261
- // And a default assetFileNames as fallback.
262
- let assetFileNames : Exclude < OutputOptions [ 'assetFileNames' ] , undefined > =
263
- ( output && ! Array . isArray ( output ) ? output . assetFileNames : undefined ) ??
264
- defaultAssetFileNames
265
- if ( output && Array . isArray ( output ) ) {
266
- // Second, if output is an array, adopt assetFileNames in the first object.
267
- assetFileNames = output [ 0 ] . assetFileNames ?? assetFileNames
268
- }
269
- return assetFileNames
270
- }
271
-
272
- /**
273
- * converts the source filepath of the asset to the output filename based on the assetFileNames option. \
274
- * this function imitates the behavior of rollup.js. \
275
- * https://rollupjs.org/guide/en/#outputassetfilenames
276
- *
277
- * @example
278
- * ```ts
279
- * const content = Buffer.from('text');
280
- * const fileName = assetFileNamesToFileName(
281
- * 'assets/[name].[hash][extname]',
282
- * '/path/to/file.txt',
283
- * getHash(content),
284
- * content
285
- * )
286
- * // fileName: 'assets/file.982d9e3e.txt'
287
- * ```
288
- *
289
- * @param assetFileNames filename pattern. e.g. `'assets/[name].[hash][extname]'`
290
- * @param file filepath of the asset
291
- * @param contentHash hash of the asset. used for `'[hash]'` placeholder
292
- * @param content content of the asset. passed to `assetFileNames` if `assetFileNames` is a function
293
- * @returns output filename
294
- */
295
- export function assetFileNamesToFileName (
296
- assetFileNames : Exclude < OutputOptions [ 'assetFileNames' ] , undefined > ,
297
- file : string ,
298
- contentHash : string ,
299
- content : string | Buffer
300
- ) : string {
301
- const basename = path . basename ( file )
302
-
303
- // placeholders for `assetFileNames`
304
- // `hash` is slightly different from the rollup's one
305
- const extname = path . extname ( basename )
306
- const ext = extname . substring ( 1 )
307
- const name = basename . slice ( 0 , - extname . length )
308
- const hash = contentHash
309
-
310
- if ( typeof assetFileNames === 'function' ) {
311
- assetFileNames = assetFileNames ( {
312
- name : file ,
313
- source : content ,
314
- type : 'asset'
315
- } )
316
- if ( typeof assetFileNames !== 'string' ) {
317
- throw new TypeError ( 'assetFileNames must return a string' )
318
- }
319
- } else if ( typeof assetFileNames !== 'string' ) {
320
- throw new TypeError ( 'assetFileNames must be a string or a function' )
321
- }
322
-
323
- const fileName = assetFileNames . replace (
324
- / \[ \w + \] / g,
325
- ( placeholder : string ) : string => {
326
- switch ( placeholder ) {
327
- case '[ext]' :
328
- return ext
329
-
330
- case '[extname]' :
331
- return extname
332
-
333
- case '[hash]' :
334
- return hash
335
-
336
- case '[name]' :
337
- return sanitizeFileName ( name )
338
- }
339
- throw new Error (
340
- `invalid placeholder ${ placeholder } in assetFileNames "${ assetFileNames } "`
341
- )
342
- }
343
- )
344
-
345
- return fileName
346
- }
347
-
348
- // taken from https://github.com/rollup/rollup/blob/a8647dac0fe46c86183be8596ef7de25bc5b4e4b/src/utils/sanitizeFileName.ts
349
- // https://datatracker.ietf.org/doc/html/rfc2396
350
- // eslint-disable-next-line no-control-regex
351
- const INVALID_CHAR_REGEX = / [ \x00 - \x1F \x7F < > * # " { } | ^ [ \] ` ; ? : & = + $ , ] / g
352
- const DRIVE_LETTER_REGEX = / ^ [ a - z ] : / i
353
- function sanitizeFileName ( name : string ) : string {
354
- const match = DRIVE_LETTER_REGEX . exec ( name )
355
- const driveLetter = match ? match [ 0 ] : ''
356
-
357
- // A `:` is only allowed as part of a windows drive letter (ex: C:\foo)
358
- // Otherwise, avoid them because they can refer to NTFS alternate data streams.
359
- return (
360
- driveLetter +
361
- name . substr ( driveLetter . length ) . replace ( INVALID_CHAR_REGEX , '_' )
362
- )
363
- }
364
-
365
254
export const publicAssetUrlCache = new WeakMap <
366
255
ResolvedConfig ,
367
256
// hash -> url
0 commit comments