Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(dev): added assets to manifest #6649

Merged
merged 13 commits into from Jun 19, 2022
41 changes: 23 additions & 18 deletions packages/vite/src/node/plugins/asset.ts
Expand Up @@ -2,7 +2,7 @@ import path from 'path'
import { parse as parseUrl } from 'url'
import fs, { promises as fsp } from 'fs'
import * as mrmime from 'mrmime'
import type { OutputOptions, PluginContext } from 'rollup'
import type { OutputOptions, PluginContext, PreRenderedAsset } from 'rollup'
import MagicString from 'magic-string'
import type { Plugin } from '../plugin'
import type { ResolvedConfig } from '../config'
Expand Down Expand Up @@ -217,6 +217,27 @@ export function getAssetFilename(
return assetHashToFilenameMap.get(config)?.get(hash)
}

export function resolveAssetFileNames(
config: ResolvedConfig
): string | ((chunkInfo: PreRenderedAsset) => string) {
const output = config.build?.rollupOptions?.output
const defaultAssetFileNames = path.posix.join(
config.build.assetsDir,
'[name].[hash][extname]'
)
// Steps to determine which assetFileNames will be actually used.
// First, if output is an object or string, use assetFileNames in it.
// And a default assetFileNames as fallback.
let assetFileNames: Exclude<OutputOptions['assetFileNames'], undefined> =
(output && !Array.isArray(output) ? output.assetFileNames : undefined) ??
defaultAssetFileNames
if (output && Array.isArray(output)) {
// Second, if output is an array, adopt assetFileNames in the first object.
assetFileNames = output[0].assetFileNames ?? assetFileNames
}
return assetFileNames
}

/**
* converts the source filepath of the asset to the output filename based on the assetFileNames option. \
* this function imitates the behavior of rollup.js. \
Expand Down Expand Up @@ -364,25 +385,9 @@ async function fileToBuiltUrl(
const contentHash = getHash(content)
const { search, hash } = parseUrl(id)
const postfix = (search || '') + (hash || '')
const output = config.build?.rollupOptions?.output

const defaultAssetFileNames = path.posix.join(
config.build.assetsDir,
'[name].[hash][extname]'
)
// Steps to determine which assetFileNames will be actually used.
// First, if output is an object or string, use assetFileNames in it.
// And a default assetFileNames as fallback.
let assetFileNames: Exclude<OutputOptions['assetFileNames'], undefined> =
(output && !Array.isArray(output) ? output.assetFileNames : undefined) ??
defaultAssetFileNames
if (output && Array.isArray(output)) {
// Second, if output is an array, adopt assetFileNames in the first object.
assetFileNames = output[0].assetFileNames ?? assetFileNames
}

const fileName = assetFileNamesToFileName(
assetFileNames,
resolveAssetFileNames(config),
file,
contentHash,
content
Expand Down
21 changes: 19 additions & 2 deletions packages/vite/src/node/plugins/css.ts
Expand Up @@ -46,13 +46,15 @@ import {
import type { Logger } from '../logger'
import { addToHTMLProxyTransformResult } from './html'
import {
assetFileNamesToFileName,
assetUrlRE,
checkPublicFile,
fileToUrl,
getAssetFilename,
publicAssetUrlCache,
publicAssetUrlRE,
publicFileToBuiltUrl
publicFileToBuiltUrl,
resolveAssetFileNames
} from './asset'

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

function ensureFileExt(name: string, ext: string) {
return path.format({ ...path.parse(name), base: undefined, ext })
}

if (config.build.cssCodeSplit) {
if (isPureCssChunk) {
// this is a shared CSS-only chunk that is empty.
pureCssChunks.add(chunk.fileName)
}
if (opts.format === 'es' || opts.format === 'cjs') {
const cssAssetName = chunk.name + '.css'
const cssAssetName = ensureFileExt(
chunk.facadeModuleId
? normalizePath(path.relative(config.root, chunk.facadeModuleId))
: chunk.name,
'.css'
)

chunkCSS = resolveAssetUrlsInCss(chunkCSS, cssAssetName)
chunkCSS = await finalizeCss(chunkCSS, true, config)

// emit corresponding css file
const fileHandle = this.emitFile({
name: cssAssetName,
fileName: assetFileNamesToFileName(
resolveAssetFileNames(config),
cssAssetName,
getHash(chunkCSS),
chunkCSS
),
type: 'asset',
source: chunkCSS
})
Expand Down
11 changes: 10 additions & 1 deletion packages/vite/src/node/plugins/manifest.ts
@@ -1,5 +1,5 @@
import path from 'path'
import type { OutputChunk } from 'rollup'
import type { OutputAsset, OutputChunk } from 'rollup'
import type { ResolvedConfig } from '..'
import type { Plugin } from '../plugin'
import { normalizePath } from '../utils'
Expand Down Expand Up @@ -99,10 +99,19 @@ export function manifestPlugin(config: ResolvedConfig): Plugin {
return manifestChunk
}

function createAsset(chunk: OutputAsset): ManifestChunk {
return {
file: chunk.fileName,
src: chunk.name
}
}

for (const file in bundle) {
const chunk = bundle[file]
if (chunk.type === 'chunk') {
manifest[getChunkName(chunk)] = createChunk(chunk)
} else if (chunk.type === 'asset' && typeof chunk.name === 'string') {
manifest[chunk.name] = createAsset(chunk)
}
}

Expand Down
Expand Up @@ -32,8 +32,12 @@ describe.runIf(isBuild)('build', () => {
test('manifest', async () => {
const manifest = readManifest('dev')
const htmlEntry = manifest['index.html']
const cssAssetEntry = manifest['global.css']
const imgAssetEntry = manifest['../images/logo.png']
expect(htmlEntry.css.length).toEqual(1)
expect(htmlEntry.assets.length).toEqual(1)
expect(cssAssetEntry?.file).not.toBeUndefined()
expect(imgAssetEntry?.file).not.toBeUndefined()
})
})

Expand Down