diff --git a/packages/vite/src/node/plugins/html.ts b/packages/vite/src/node/plugins/html.ts
index cb9bf87192258d..537f58470a9cbd 100644
--- a/packages/vite/src/node/plugins/html.ts
+++ b/packages/vite/src/node/plugins/html.ts
@@ -717,7 +717,7 @@ export function buildHtmlPlugin(config: ResolvedConfig): Plugin {
},
async generateBundle(options, bundle) {
- const analyzedChunk = new Map()
+ const analyzedImportedCssFiles = new Map()
const inlineEntryChunk = new Set()
const getImportedChunks = (
chunk: OutputChunk,
@@ -777,39 +777,62 @@ export function buildHtmlPlugin(config: ResolvedConfig): Plugin {
},
})
- const getCssTagsForChunk = (
- chunk: OutputChunk,
+ const toStyleSheetLinkTag = (
+ file: string,
toOutputPath: (filename: string) => string,
- seen: Set = new Set(),
- ): HtmlTagDescriptor[] => {
- const tags: HtmlTagDescriptor[] = []
- if (!analyzedChunk.has(chunk)) {
- analyzedChunk.set(chunk, 1)
- chunk.imports.forEach((file) => {
- const importee = bundle[file]
- if (importee?.type === 'chunk') {
- tags.push(...getCssTagsForChunk(importee, toOutputPath, seen))
- }
- })
+ ): HtmlTagDescriptor => ({
+ tag: 'link',
+ attrs: {
+ rel: 'stylesheet',
+ crossorigin: true,
+ href: toOutputPath(file),
+ },
+ })
+
+ const getCssFilesForChunk = (
+ chunk: OutputChunk,
+ seenChunks: Set = new Set(),
+ seenCss: Set = new Set(),
+ ): string[] => {
+ if (seenChunks.has(chunk.fileName)) {
+ return []
+ }
+ seenChunks.add(chunk.fileName)
+
+ if (analyzedImportedCssFiles.has(chunk)) {
+ const files = analyzedImportedCssFiles.get(chunk)!
+ const additionals = files.filter((file) => !seenCss.has(file))
+ additionals.forEach((file) => seenCss.add(file))
+ return additionals
}
+ const files: string[] = []
+ chunk.imports.forEach((file) => {
+ const importee = bundle[file]
+ if (importee?.type === 'chunk') {
+ files.push(...getCssFilesForChunk(importee, seenChunks, seenCss))
+ }
+ })
+ analyzedImportedCssFiles.set(chunk, files)
+
chunk.viteMetadata!.importedCss.forEach((file) => {
- if (!seen.has(file)) {
- seen.add(file)
- tags.push({
- tag: 'link',
- attrs: {
- rel: 'stylesheet',
- crossorigin: true,
- href: toOutputPath(file),
- },
- })
+ if (!seenCss.has(file)) {
+ seenCss.add(file)
+ files.push(file)
}
})
- return tags
+ return files
}
+ const getCssTagsForChunk = (
+ chunk: OutputChunk,
+ toOutputPath: (filename: string) => string,
+ ) =>
+ getCssFilesForChunk(chunk).map((file) =>
+ toStyleSheetLinkTag(file, toOutputPath),
+ )
+
for (const [normalizedId, html] of processedHtml(this)) {
const relativeUrlPath = normalizePath(
path.relative(config.root, normalizedId),