Skip to content

Commit cdf744d

Browse files
lubomirblazekczjessarcherpatak-dev
authored
feat(dev): added assets to manifest (#6649)
Co-authored-by: Jess Archer <[email protected]> Co-authored-by: patak-dev <[email protected]>
1 parent 1b820da commit cdf744d

File tree

4 files changed

+56
-21
lines changed

4 files changed

+56
-21
lines changed

packages/vite/src/node/plugins/asset.ts

+23-18
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import path from 'path'
22
import { parse as parseUrl } from 'url'
33
import fs, { promises as fsp } from 'fs'
44
import * as mrmime from 'mrmime'
5-
import type { OutputOptions, PluginContext } from 'rollup'
5+
import type { OutputOptions, PluginContext, PreRenderedAsset } from 'rollup'
66
import MagicString from 'magic-string'
77
import type { Plugin } from '../plugin'
88
import type { ResolvedConfig } from '../config'
@@ -217,6 +217,27 @@ export function getAssetFilename(
217217
return assetHashToFilenameMap.get(config)?.get(hash)
218218
}
219219

220+
export function resolveAssetFileNames(
221+
config: ResolvedConfig
222+
): string | ((chunkInfo: PreRenderedAsset) => string) {
223+
const output = config.build?.rollupOptions?.output
224+
const defaultAssetFileNames = path.posix.join(
225+
config.build.assetsDir,
226+
'[name].[hash][extname]'
227+
)
228+
// Steps to determine which assetFileNames will be actually used.
229+
// First, if output is an object or string, use assetFileNames in it.
230+
// And a default assetFileNames as fallback.
231+
let assetFileNames: Exclude<OutputOptions['assetFileNames'], undefined> =
232+
(output && !Array.isArray(output) ? output.assetFileNames : undefined) ??
233+
defaultAssetFileNames
234+
if (output && Array.isArray(output)) {
235+
// Second, if output is an array, adopt assetFileNames in the first object.
236+
assetFileNames = output[0].assetFileNames ?? assetFileNames
237+
}
238+
return assetFileNames
239+
}
240+
220241
/**
221242
* converts the source filepath of the asset to the output filename based on the assetFileNames option. \
222243
* this function imitates the behavior of rollup.js. \
@@ -364,25 +385,9 @@ async function fileToBuiltUrl(
364385
const contentHash = getHash(content)
365386
const { search, hash } = parseUrl(id)
366387
const postfix = (search || '') + (hash || '')
367-
const output = config.build?.rollupOptions?.output
368-
369-
const defaultAssetFileNames = path.posix.join(
370-
config.build.assetsDir,
371-
'[name].[hash][extname]'
372-
)
373-
// Steps to determine which assetFileNames will be actually used.
374-
// First, if output is an object or string, use assetFileNames in it.
375-
// And a default assetFileNames as fallback.
376-
let assetFileNames: Exclude<OutputOptions['assetFileNames'], undefined> =
377-
(output && !Array.isArray(output) ? output.assetFileNames : undefined) ??
378-
defaultAssetFileNames
379-
if (output && Array.isArray(output)) {
380-
// Second, if output is an array, adopt assetFileNames in the first object.
381-
assetFileNames = output[0].assetFileNames ?? assetFileNames
382-
}
383388

384389
const fileName = assetFileNamesToFileName(
385-
assetFileNames,
390+
resolveAssetFileNames(config),
386391
file,
387392
contentHash,
388393
content

packages/vite/src/node/plugins/css.ts

+19-2
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,15 @@ import {
4646
import type { Logger } from '../logger'
4747
import { addToHTMLProxyTransformResult } from './html'
4848
import {
49+
assetFileNamesToFileName,
4950
assetUrlRE,
5051
checkPublicFile,
5152
fileToUrl,
5253
getAssetFilename,
5354
publicAssetUrlCache,
5455
publicAssetUrlRE,
55-
publicFileToBuiltUrl
56+
publicFileToBuiltUrl,
57+
resolveAssetFileNames
5658
} from './asset'
5759

5860
// const debug = createDebugger('vite:css')
@@ -487,20 +489,35 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin {
487489
return chunkCSS
488490
}
489491

492+
function ensureFileExt(name: string, ext: string) {
493+
return path.format({ ...path.parse(name), base: undefined, ext })
494+
}
495+
490496
if (config.build.cssCodeSplit) {
491497
if (isPureCssChunk) {
492498
// this is a shared CSS-only chunk that is empty.
493499
pureCssChunks.add(chunk.fileName)
494500
}
495501
if (opts.format === 'es' || opts.format === 'cjs') {
496-
const cssAssetName = chunk.name + '.css'
502+
const cssAssetName = ensureFileExt(
503+
chunk.facadeModuleId
504+
? normalizePath(path.relative(config.root, chunk.facadeModuleId))
505+
: chunk.name,
506+
'.css'
507+
)
497508

498509
chunkCSS = resolveAssetUrlsInCss(chunkCSS, cssAssetName)
499510
chunkCSS = await finalizeCss(chunkCSS, true, config)
500511

501512
// emit corresponding css file
502513
const fileHandle = this.emitFile({
503514
name: cssAssetName,
515+
fileName: assetFileNamesToFileName(
516+
resolveAssetFileNames(config),
517+
cssAssetName,
518+
getHash(chunkCSS),
519+
chunkCSS
520+
),
504521
type: 'asset',
505522
source: chunkCSS
506523
})

packages/vite/src/node/plugins/manifest.ts

+10-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import path from 'path'
2-
import type { OutputChunk } from 'rollup'
2+
import type { OutputAsset, OutputChunk } from 'rollup'
33
import type { ResolvedConfig } from '..'
44
import type { Plugin } from '../plugin'
55
import { normalizePath } from '../utils'
@@ -99,10 +99,19 @@ export function manifestPlugin(config: ResolvedConfig): Plugin {
9999
return manifestChunk
100100
}
101101

102+
function createAsset(chunk: OutputAsset): ManifestChunk {
103+
return {
104+
file: chunk.fileName,
105+
src: chunk.name
106+
}
107+
}
108+
102109
for (const file in bundle) {
103110
const chunk = bundle[file]
104111
if (chunk.type === 'chunk') {
105112
manifest[getChunkName(chunk)] = createChunk(chunk)
113+
} else if (chunk.type === 'asset' && typeof chunk.name === 'string') {
114+
manifest[chunk.name] = createAsset(chunk)
106115
}
107116
}
108117

playground/backend-integration/__tests__/backend-integration.spec.ts

+4
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,12 @@ describe.runIf(isBuild)('build', () => {
3232
test('manifest', async () => {
3333
const manifest = readManifest('dev')
3434
const htmlEntry = manifest['index.html']
35+
const cssAssetEntry = manifest['global.css']
36+
const imgAssetEntry = manifest['../images/logo.png']
3537
expect(htmlEntry.css.length).toEqual(1)
3638
expect(htmlEntry.assets.length).toEqual(1)
39+
expect(cssAssetEntry?.file).not.toBeUndefined()
40+
expect(imgAssetEntry?.file).not.toBeUndefined()
3741
})
3842
})
3943

0 commit comments

Comments
 (0)