Skip to content

Commit 8e30025

Browse files
sun0daybluwy
andauthoredApr 5, 2023
fix(css): css file emit synchronously (#12558)
Co-authored-by: bluwy <bjornlu.dev@gmail.com>
1 parent 4ffaeee commit 8e30025

File tree

4 files changed

+81
-58
lines changed

4 files changed

+81
-58
lines changed
 

‎package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@
7979
"prompts": "^2.4.2",
8080
"resolve": "^1.22.1",
8181
"rimraf": "^4.4.0",
82-
"rollup": "^3.20.0",
82+
"rollup": "^3.20.2",
8383
"semver": "^7.3.8",
8484
"simple-git-hooks": "^2.8.1",
8585
"tslib": "^2.5.0",

‎packages/vite/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@
6969
"esbuild": "^0.17.5",
7070
"postcss": "^8.4.21",
7171
"resolve": "^1.22.1",
72-
"rollup": "^3.20.0"
72+
"rollup": "^3.20.2"
7373
},
7474
"optionalDependencies": {
7575
"fsevents": "~2.3.2"

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

+24-1
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,8 @@ export function cssPlugin(config: ResolvedConfig): Plugin {
316316
export function cssPostPlugin(config: ResolvedConfig): Plugin {
317317
// styles initialization in buildStart causes a styling loss in watch
318318
const styles: Map<string, string> = new Map<string, string>()
319+
// list of css emit tasks to guarantee the files are emitted in a deterministic order
320+
let emitTasks: Promise<void>[] = []
319321
let pureCssChunks: Set<RenderedChunk>
320322

321323
// when there are multiple rollup outputs and extracting CSS, only emit once,
@@ -353,6 +355,7 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin {
353355
pureCssChunks = new Set<RenderedChunk>()
354356
outputToExtractedCSSMap = new Map<NormalizedOutputOptions, string>()
355357
hasEmitted = false
358+
emitTasks = []
356359
},
357360

358361
async transform(css, id, options) {
@@ -563,7 +566,22 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin {
563566
const cssFileName = ensureFileExt(cssAssetName, '.css')
564567

565568
chunkCSS = resolveAssetUrlsInCss(chunkCSS, cssAssetName)
566-
chunkCSS = await finalizeCss(chunkCSS, true, config)
569+
570+
const previousTask = emitTasks[emitTasks.length - 1]
571+
// finalizeCss is async which makes `emitFile` non-deterministic, so
572+
// we use a `.then` to wait for previous tasks before finishing this
573+
const thisTask = finalizeCss(chunkCSS, true, config).then((css) => {
574+
chunkCSS = css
575+
// make sure the previous task is also finished, this works recursively
576+
return previousTask
577+
})
578+
579+
// push this task so the next task can wait for this one
580+
emitTasks.push(thisTask)
581+
const emitTasksLength = emitTasks.length
582+
583+
// wait for this and previous tasks to finish
584+
await thisTask
567585

568586
// emit corresponding css file
569587
const referenceId = this.emitFile({
@@ -577,6 +595,11 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin {
577595
.get(config)!
578596
.set(referenceId, { originalName, isEntry })
579597
chunk.viteMetadata!.importedCss.add(this.getFileName(referenceId))
598+
599+
if (emitTasksLength === emitTasks.length) {
600+
// this is the last task, clear `emitTasks` to free up memory
601+
emitTasks = []
602+
}
580603
} else if (!config.build.ssr) {
581604
// legacy build and inline css
582605

‎pnpm-lock.yaml

+55-55
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)
Please sign in to comment.