diff --git a/packages/vite/src/node/index.ts b/packages/vite/src/node/index.ts index 8c2ca11306ae4a..f35ddae570e027 100644 --- a/packages/vite/src/node/index.ts +++ b/packages/vite/src/node/index.ts @@ -58,6 +58,7 @@ export type { HtmlTagDescriptor } from './plugins/html' export type { CSSOptions, CSSModulesOptions } from './plugins/css' +export type { ChunkMetadata } from './plugins/metadata' export type { JsonOptions } from './plugins/json' export type { TransformOptions as EsbuildTransformOptions } from 'esbuild' export type { ESBuildOptions, ESBuildTransformResult } from './plugins/esbuild' @@ -92,9 +93,10 @@ export type { RollupCommonJSOptions } from 'types/commonjs' export type { RollupDynamicImportVarsOptions } from 'types/dynamicImportVars' export type { Matcher, AnymatchPattern, AnymatchFn } from 'types/anymatch' +import type { ChunkMetadata } from './plugins/metadata' + declare module 'rollup' { export interface RenderedChunk { - importedAssets: Set - importedCss: Set + viteMetadata: ChunkMetadata } } diff --git a/packages/vite/src/node/plugins/asset.ts b/packages/vite/src/node/plugins/asset.ts index c54b3da1b83442..86f05126416c57 100644 --- a/packages/vite/src/node/plugins/asset.ts +++ b/packages/vite/src/node/plugins/asset.ts @@ -77,8 +77,6 @@ export function assetPlugin(config: ResolvedConfig): Plugin { }, renderChunk(code, chunk) { - chunk.importedAssets = new Set() - let match: RegExpExecArray | null let s: MagicString | undefined @@ -96,7 +94,7 @@ export function assetPlugin(config: ResolvedConfig): Plugin { // some internal plugins may still need to emit chunks (e.g. worker) so // fallback to this.getFileName for that. const file = getAssetFilename(hash, config) || this.getFileName(hash) - chunk.importedAssets.add(cleanUrl(file)) + chunk.viteMetadata.importedAssets.add(cleanUrl(file)) const outputFilepath = config.base + file + postfix s.overwrite(match.index, match.index + full.length, outputFilepath) } diff --git a/packages/vite/src/node/plugins/css.ts b/packages/vite/src/node/plugins/css.ts index e643272b6d9761..be1ca6a7d07090 100644 --- a/packages/vite/src/node/plugins/css.ts +++ b/packages/vite/src/node/plugins/css.ts @@ -364,8 +364,6 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin { } } - chunk.importedCss = new Set() - if (!chunkCSS) { return null } @@ -386,7 +384,7 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin { const isRelativeBase = config.base === '' || config.base.startsWith('.') css = css.replace(assetUrlRE, (_, fileHash, postfix = '') => { const filename = getAssetFilename(fileHash, config) + postfix - chunk.importedAssets.add(cleanUrl(filename)) + chunk.viteMetadata.importedAssets.add(cleanUrl(filename)) if (!isRelativeBase || inlined) { // absolute base or relative base but inlined (injected as style tag into // index.html) use the base as-is @@ -423,7 +421,7 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin { type: 'asset', source: chunkCSS }) - chunk.importedCss.add(this.getFileName(fileHandle)) + chunk.viteMetadata.importedCss.add(this.getFileName(fileHandle)) } else if (!config.build.ssr) { // legacy build, inline css chunkCSS = await processChunkCSS(chunkCSS, { @@ -481,8 +479,12 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin { // chunks instead. chunk.imports = chunk.imports.filter((file) => { if (pureCssChunks.has(file)) { - const { importedCss } = bundle[file] as OutputChunk - importedCss.forEach((file) => chunk.importedCss.add(file)) + const { + viteMetadata: { importedCss } + } = bundle[file] as OutputChunk + importedCss.forEach((file) => + chunk.viteMetadata.importedCss.add(file) + ) return false } return true diff --git a/packages/vite/src/node/plugins/html.ts b/packages/vite/src/node/plugins/html.ts index 4dae2d5e8ccd17..e123ca27abc779 100644 --- a/packages/vite/src/node/plugins/html.ts +++ b/packages/vite/src/node/plugins/html.ts @@ -532,7 +532,7 @@ export function buildHtmlPlugin(config: ResolvedConfig): Plugin { }) } - chunk.importedCss.forEach((file) => { + chunk.viteMetadata.importedCss.forEach((file) => { if (!seen.has(file)) { seen.add(file) tags.push({ diff --git a/packages/vite/src/node/plugins/importAnalysisBuild.ts b/packages/vite/src/node/plugins/importAnalysisBuild.ts index 881cd1925dbca8..3c7f231cc10b5b 100644 --- a/packages/vite/src/node/plugins/importAnalysisBuild.ts +++ b/packages/vite/src/node/plugins/importAnalysisBuild.ts @@ -277,7 +277,7 @@ export function buildImportAnalysisPlugin(config: ResolvedConfig): Plugin { const chunk = bundle[filename] as OutputChunk | undefined if (chunk) { deps.add(chunk.fileName) - chunk.importedCss.forEach((file) => { + chunk.viteMetadata.importedCss.forEach((file) => { deps.add(file) }) chunk.imports.forEach(addDeps) @@ -286,8 +286,8 @@ export function buildImportAnalysisPlugin(config: ResolvedConfig): Plugin { removedPureCssFilesCache.get(config)! const chunk = removedPureCssFiles.get(filename) if (chunk) { - if (chunk.importedCss.size) { - chunk.importedCss.forEach((file) => { + if (chunk.viteMetadata.importedCss.size) { + chunk.viteMetadata.importedCss.forEach((file) => { deps.add(file) }) hasRemovedPureCssChunk = true diff --git a/packages/vite/src/node/plugins/index.ts b/packages/vite/src/node/plugins/index.ts index e4f3d453527af3..5213714febb12b 100644 --- a/packages/vite/src/node/plugins/index.ts +++ b/packages/vite/src/node/plugins/index.ts @@ -16,6 +16,7 @@ import { preAliasPlugin } from './preAlias' import { definePlugin } from './define' import { ssrRequireHookPlugin } from './ssrRequireHook' import { workerImportMetaUrlPlugin } from './workerImportMetaUrl' +import { metadataPlugin } from './metadata' export async function resolvePlugins( config: ResolvedConfig, @@ -30,6 +31,7 @@ export async function resolvePlugins( : { pre: [], post: [] } return [ + isBuild ? metadataPlugin() : null, isBuild ? null : preAliasPlugin(), aliasPlugin({ entries: config.resolve.alias }), ...prePlugins, diff --git a/packages/vite/src/node/plugins/manifest.ts b/packages/vite/src/node/plugins/manifest.ts index b89714780022a0..194f84c680ef16 100644 --- a/packages/vite/src/node/plugins/manifest.ts +++ b/packages/vite/src/node/plugins/manifest.ts @@ -88,11 +88,11 @@ export function manifestPlugin(config: ResolvedConfig): Plugin { } } - if (chunk.importedCss.size) { - manifestChunk.css = [...chunk.importedCss] + if (chunk.viteMetadata.importedCss.size) { + manifestChunk.css = [...chunk.viteMetadata.importedCss] } - if (chunk.importedAssets.size) { - manifestChunk.assets = [...chunk.importedAssets] + if (chunk.viteMetadata.importedAssets.size) { + manifestChunk.assets = [...chunk.viteMetadata.importedAssets] } return manifestChunk diff --git a/packages/vite/src/node/plugins/metadata.ts b/packages/vite/src/node/plugins/metadata.ts new file mode 100644 index 00000000000000..2b617aca4c89c8 --- /dev/null +++ b/packages/vite/src/node/plugins/metadata.ts @@ -0,0 +1,23 @@ +import type { Plugin } from '../plugin' + +export interface ChunkMetadata { + importedAssets: Set + importedCss: Set +} + +/** + * Prepares the rendered chunks to contain additional metadata during build. + */ +export function metadataPlugin(): Plugin { + return { + name: 'vite:build-metadata', + + async renderChunk(_code, chunk) { + chunk.viteMetadata = { + importedAssets: new Set(), + importedCss: new Set() + } + return null + } + } +} diff --git a/packages/vite/src/node/ssr/ssrManifestPlugin.ts b/packages/vite/src/node/ssr/ssrManifestPlugin.ts index e6bff1289e10f3..84cdfcc3569a16 100644 --- a/packages/vite/src/node/ssr/ssrManifestPlugin.ts +++ b/packages/vite/src/node/ssr/ssrManifestPlugin.ts @@ -26,11 +26,11 @@ export function ssrManifestPlugin(config: ResolvedConfig): Plugin { mappedChunks.push(base + chunk.fileName) // tags for entry chunks are already generated in static HTML, // so we only need to record info for non-entry chunks. - chunk.importedCss.forEach((file) => { + chunk.viteMetadata.importedCss.forEach((file) => { mappedChunks.push(base + file) }) } - chunk.importedAssets.forEach((file) => { + chunk.viteMetadata.importedAssets.forEach((file) => { mappedChunks.push(base + file) }) } @@ -64,7 +64,7 @@ export function ssrManifestPlugin(config: ResolvedConfig): Plugin { analyzed.add(filename) const chunk = bundle[filename] as OutputChunk | undefined if (chunk) { - chunk.importedCss.forEach((file) => { + chunk.viteMetadata.importedCss.forEach((file) => { deps.push(`/${file}`) }) chunk.imports.forEach(addDeps)