Skip to content

Commit

Permalink
fix(css): Ensure dynamic chunks are always extracted last to overwrit…
Browse files Browse the repository at this point in the history
…e the styles

Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
  • Loading branch information
susnux committed Jun 8, 2024
1 parent 2f1c3d3 commit f34bc55
Showing 1 changed file with 11 additions and 5 deletions.
16 changes: 11 additions & 5 deletions packages/vite/src/node/plugins/css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -845,28 +845,34 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin {
function extractCss() {
let css = ''
const collected = new Set<OutputChunk>()
// will be populated in order they are used by entry points
const dynamicImports = new Set<string>()

function collect(chunk: OutputChunk | OutputAsset) {
if (!chunk || chunk.type !== 'chunk' || collected.has(chunk)) return
collected.add(chunk)

// First collect all styles from the synchronous imports (lowest priority)
chunk.imports.forEach((importName) => collect(bundle[importName]))
// Save dynamic imports in deterministic order to add the styles later (to have the highest priority)
chunk.dynamicImports.forEach((importName) =>
collect(bundle[importName]),
dynamicImports.add(importName),
)
// Then collect the styles of the current chunk (might overwrite some styles from previous imports)
css += chunkCSSMap.get(chunk.preliminaryFileName) ?? ''
}

// The bundle is guaranteed to be deterministic, if not then we have a bug in rollup.
// So we use it to ensure a deterministic order of styles
for (const chunk of Object.values(bundle)) {
if (
chunk.type === 'chunk' &&
(chunk.isEntry || chunk.isDynamicEntry)
) {
if (chunk.type === 'chunk' && chunk.isEntry) {
collect(chunk)
}
}
// Now collect the dynamic chunks, this is done last to have the styles overwrite the previous ones
for (const chunkName of dynamicImports) {
collect(bundle[chunkName])
}

return css
}
Expand Down

0 comments on commit f34bc55

Please sign in to comment.