From 671dab01a648c49088cd626ece5adef9e1822d48 Mon Sep 17 00:00:00 2001 From: ivan Date: Fri, 24 Mar 2023 10:15:41 +0800 Subject: [PATCH 1/4] fix: css file emit synchronously --- packages/vite/src/node/plugins/css.ts | 65 +++++++++++++++++++++------ 1 file changed, 52 insertions(+), 13 deletions(-) diff --git a/packages/vite/src/node/plugins/css.ts b/packages/vite/src/node/plugins/css.ts index d5fa61ed6eef28..f9bc381cfa0aa6 100644 --- a/packages/vite/src/node/plugins/css.ts +++ b/packages/vite/src/node/plugins/css.ts @@ -316,6 +316,9 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin { // styles initialization in buildStart causes a styling loss in watch const styles: Map = new Map() let pureCssChunks: Set + let emitTasks: Set<{ name: string; emit: () => Promise }> + let sortedEmitTasks: { name: string; emit: () => Promise }[] + let emitTaskRunning = false // when there are multiple rollup outputs and extracting CSS, only emit once, // since output formats have no effect on the generated CSS. @@ -352,6 +355,9 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin { pureCssChunks = new Set() outputToExtractedCSSMap = new Map() hasEmitted = false + emitTasks = new Set<{ name: string; emit: () => Promise }>() + sortedEmitTasks = [] + emitTaskRunning = false }, async transform(css, id, options) { @@ -562,20 +568,53 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin { const cssFileName = ensureFileExt(cssAssetName, '.css') chunkCSS = resolveAssetUrlsInCss(chunkCSS, cssAssetName) - chunkCSS = await finalizeCss(chunkCSS, true, config) - - // emit corresponding css file - const referenceId = this.emitFile({ - name: path.basename(cssFileName), - type: 'asset', - source: chunkCSS, + const emitName = path.basename(cssFileName) + + emitTasks.add({ + name: emitName, + emit: async () => { + chunkCSS = await finalizeCss(chunkCSS, true, config) + + // emit corresponding css file + const referenceId = this.emitFile({ + name: emitName, + type: 'asset', + source: chunkCSS, + }) + const originalName = isPreProcessor(lang) + ? cssAssetName + : cssFileName + const isEntry = chunk.isEntry && isPureCssChunk + generatedAssets + .get(config)! + .set(referenceId, { originalName, isEntry }) + chunk.viteMetadata!.importedCss.add(this.getFileName(referenceId)) + }, }) - const originalName = isPreProcessor(lang) ? cssAssetName : cssFileName - const isEntry = chunk.isEntry && isPureCssChunk - generatedAssets - .get(config)! - .set(referenceId, { originalName, isEntry }) - chunk.viteMetadata!.importedCss.add(this.getFileName(referenceId)) + + const runEmitTasks = async () => { + if (emitTaskRunning) { + return + } + emitTaskRunning = true + for (const { emit } of sortedEmitTasks) { + await emit() + } + } + + // wait for collecting all emitFile + await sortedEmitTasks + + if (!sortedEmitTasks.length) { + sortedEmitTasks = Array.from(emitTasks).sort((next, cur) => { + return next.name.length > cur.name.length || + (next.name.length === cur.name.length && next.name > cur.name) + ? 1 + : -1 + }) + } + + await runEmitTasks() } else if (!config.build.ssr) { // legacy build and inline css From 279904a825467bc2d0eaacfed21f7305addc3ad8 Mon Sep 17 00:00:00 2001 From: ivan Date: Fri, 24 Mar 2023 10:18:21 +0800 Subject: [PATCH 2/4] chore: upgrade rollup to 3.20.1 --- package.json | 2 +- packages/vite/package.json | 2 +- pnpm-lock.yaml | 104 ++++++++++++++++++------------------- 3 files changed, 54 insertions(+), 54 deletions(-) diff --git a/package.json b/package.json index c11f1c8b286228..24b80354686b2c 100644 --- a/package.json +++ b/package.json @@ -79,7 +79,7 @@ "prompts": "^2.4.2", "resolve": "^1.22.1", "rimraf": "^4.4.0", - "rollup": "^3.20.0", + "rollup": "^3.20.1", "semver": "^7.3.8", "simple-git-hooks": "^2.8.1", "tslib": "^2.5.0", diff --git a/packages/vite/package.json b/packages/vite/package.json index c0cda5f120aa97..729963be61b889 100644 --- a/packages/vite/package.json +++ b/packages/vite/package.json @@ -69,7 +69,7 @@ "esbuild": "^0.17.5", "postcss": "^8.4.21", "resolve": "^1.22.1", - "rollup": "^3.20.0" + "rollup": "^3.20.1" }, "optionalDependencies": { "fsevents": "~2.3.2" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0d1c28430fb3d5..ce2d4c1308d237 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -60,7 +60,7 @@ importers: prompts: ^2.4.2 resolve: ^1.22.1 rimraf: ^4.4.0 - rollup: ^3.20.0 + rollup: ^3.20.1 semver: ^7.3.8 simple-git-hooks: ^2.8.1 tslib: ^2.5.0 @@ -74,7 +74,7 @@ importers: devDependencies: '@babel/types': 7.21.3 '@microsoft/api-extractor': 7.34.4_@types+node@18.15.5 - '@rollup/plugin-typescript': 11.0.0_ic46el5hfgdxjspsfr4ii6ggfa + '@rollup/plugin-typescript': 11.0.0_nq7tmx6k5udhfqoe4bwkrsqtd4 '@types/babel__core': 7.20.0 '@types/babel__standalone': 7.1.4 '@types/convert-source-map': 2.0.0 @@ -115,7 +115,7 @@ importers: prompts: 2.4.2 resolve: 1.22.1 rimraf: 4.4.0 - rollup: 3.20.0 + rollup: 3.20.1 semver: 7.3.8 simple-git-hooks: 2.8.1 tslib: 2.5.0 @@ -216,7 +216,7 @@ importers: postcss-modules: ^6.0.0 resolve: ^1.22.1 resolve.exports: ^2.0.1 - rollup: ^3.20.0 + rollup: ^3.20.1 rollup-plugin-license: ^3.0.1 sirv: ^2.0.2 source-map-js: ^1.0.2 @@ -232,7 +232,7 @@ importers: esbuild: 0.17.5 postcss: 8.4.21 resolve: 1.22.1 - rollup: 3.20.0 + rollup: 3.20.1 optionalDependencies: fsevents: 2.3.2 devDependencies: @@ -240,13 +240,13 @@ importers: '@babel/parser': 7.21.3 '@babel/types': 7.21.3 '@jridgewell/trace-mapping': 0.3.17 - '@rollup/plugin-alias': 4.0.3_rollup@3.20.0 - '@rollup/plugin-commonjs': 24.0.1_rollup@3.20.0 - '@rollup/plugin-dynamic-import-vars': 2.0.3_rollup@3.20.0 - '@rollup/plugin-json': 6.0.0_rollup@3.20.0 - '@rollup/plugin-node-resolve': 15.0.1_rollup@3.20.0 - '@rollup/plugin-typescript': 11.0.0_rollup@3.20.0+tslib@2.5.0 - '@rollup/pluginutils': 5.0.2_rollup@3.20.0 + '@rollup/plugin-alias': 4.0.3_rollup@3.20.1 + '@rollup/plugin-commonjs': 24.0.1_rollup@3.20.1 + '@rollup/plugin-dynamic-import-vars': 2.0.3_rollup@3.20.1 + '@rollup/plugin-json': 6.0.0_rollup@3.20.1 + '@rollup/plugin-node-resolve': 15.0.1_rollup@3.20.1 + '@rollup/plugin-typescript': 11.0.0_rollup@3.20.1+tslib@2.5.0 + '@rollup/pluginutils': 5.0.2_rollup@3.20.1 '@types/pnpapi': 0.0.2 acorn: 8.8.2 acorn-walk: 8.2.0_acorn@8.8.2 @@ -282,7 +282,7 @@ importers: postcss-load-config: 4.0.1_postcss@8.4.21 postcss-modules: 6.0.0_postcss@8.4.21 resolve.exports: 2.0.1 - rollup-plugin-license: 3.0.1_rollup@3.20.0 + rollup-plugin-license: 3.0.1_rollup@3.20.1 sirv: 2.0.2_hmoqtj4vy3i7wnpchga2a2mu3y source-map-js: 1.0.2 source-map-support: 0.5.21 @@ -3174,7 +3174,7 @@ packages: resolution: {integrity: sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==} dev: true - /@rollup/plugin-alias/4.0.3_rollup@3.20.0: + /@rollup/plugin-alias/4.0.3_rollup@3.20.1: resolution: {integrity: sha512-ZuDWE1q4PQDhvm/zc5Prun8sBpLJy41DMptYrS6MhAy9s9kL/doN1613BWfEchGVfKxzliJ3BjbOPizXX38DbQ==} engines: {node: '>=14.0.0'} peerDependencies: @@ -3183,11 +3183,11 @@ packages: rollup: optional: true dependencies: - rollup: 3.20.0 + rollup: 3.20.1 slash: 4.0.0 dev: true - /@rollup/plugin-commonjs/24.0.1_rollup@3.20.0: + /@rollup/plugin-commonjs/24.0.1_rollup@3.20.1: resolution: {integrity: sha512-15LsiWRZk4eOGqvrJyu3z3DaBu5BhXIMeWnijSRvd8irrrg9SHpQ1pH+BUK4H6Z9wL9yOxZJMTLU+Au86XHxow==} engines: {node: '>=14.0.0'} peerDependencies: @@ -3196,16 +3196,16 @@ packages: rollup: optional: true dependencies: - '@rollup/pluginutils': 5.0.2_rollup@3.20.0 + '@rollup/pluginutils': 5.0.2_rollup@3.20.1 commondir: 1.0.1 estree-walker: 2.0.2 glob: 8.0.3 is-reference: 1.2.1 magic-string: 0.27.0 - rollup: 3.20.0 + rollup: 3.20.1 dev: true - /@rollup/plugin-dynamic-import-vars/2.0.3_rollup@3.20.0: + /@rollup/plugin-dynamic-import-vars/2.0.3_rollup@3.20.1: resolution: {integrity: sha512-0zQV0TDDewilU+7ZLmwc0u44SkeRxSxMdINBuX5isrQGJ6EdTjVL1TcnOZ9In99byaSGAQnHmSFw+6hm0E/jrw==} engines: {node: '>=14.0.0'} peerDependencies: @@ -3214,14 +3214,14 @@ packages: rollup: optional: true dependencies: - '@rollup/pluginutils': 5.0.2_rollup@3.20.0 + '@rollup/pluginutils': 5.0.2_rollup@3.20.1 estree-walker: 2.0.2 fast-glob: 3.2.12 magic-string: 0.27.0 - rollup: 3.20.0 + rollup: 3.20.1 dev: true - /@rollup/plugin-json/6.0.0_rollup@3.20.0: + /@rollup/plugin-json/6.0.0_rollup@3.20.1: resolution: {integrity: sha512-i/4C5Jrdr1XUarRhVu27EEwjt4GObltD7c+MkCIpO2QIbojw8MUs+CCTqOphQi3Qtg1FLmYt+l+6YeoIf51J7w==} engines: {node: '>=14.0.0'} peerDependencies: @@ -3230,11 +3230,11 @@ packages: rollup: optional: true dependencies: - '@rollup/pluginutils': 5.0.2_rollup@3.20.0 - rollup: 3.20.0 + '@rollup/pluginutils': 5.0.2_rollup@3.20.1 + rollup: 3.20.1 dev: true - /@rollup/plugin-node-resolve/15.0.1_rollup@3.20.0: + /@rollup/plugin-node-resolve/15.0.1_rollup@3.20.1: resolution: {integrity: sha512-ReY88T7JhJjeRVbfCyNj+NXAG3IIsVMsX9b5/9jC98dRP8/yxlZdz7mHZbHk5zHr24wZZICS5AcXsFZAXYUQEg==} engines: {node: '>=14.0.0'} peerDependencies: @@ -3243,16 +3243,16 @@ packages: rollup: optional: true dependencies: - '@rollup/pluginutils': 5.0.2_rollup@3.20.0 + '@rollup/pluginutils': 5.0.2_rollup@3.20.1 '@types/resolve': 1.20.2 deepmerge: 4.2.2 is-builtin-module: 3.2.0 is-module: 1.0.0 resolve: 1.22.1 - rollup: 3.20.0 + rollup: 3.20.1 dev: true - /@rollup/plugin-replace/5.0.2_rollup@3.20.0: + /@rollup/plugin-replace/5.0.2_rollup@3.20.1: resolution: {integrity: sha512-M9YXNekv/C/iHHK+cvORzfRYfPbq0RDD8r0G+bMiTXjNGKulPnCT9O3Ss46WfhI6ZOCgApOP7xAdmCQJ+U2LAA==} engines: {node: '>=14.0.0'} peerDependencies: @@ -3261,12 +3261,12 @@ packages: rollup: optional: true dependencies: - '@rollup/pluginutils': 5.0.2_rollup@3.20.0 + '@rollup/pluginutils': 5.0.2_rollup@3.20.1 magic-string: 0.27.0 - rollup: 3.20.0 + rollup: 3.20.1 dev: true - /@rollup/plugin-typescript/11.0.0_ic46el5hfgdxjspsfr4ii6ggfa: + /@rollup/plugin-typescript/11.0.0_nq7tmx6k5udhfqoe4bwkrsqtd4: resolution: {integrity: sha512-goPyCWBiimk1iJgSTgsehFD5OOFHiAknrRJjqFCudcW8JtWiBlK284Xnn4flqMqg6YAjVG/EE+3aVzrL5qNSzQ==} engines: {node: '>=14.0.0'} peerDependencies: @@ -3279,14 +3279,14 @@ packages: tslib: optional: true dependencies: - '@rollup/pluginutils': 5.0.2_rollup@3.20.0 + '@rollup/pluginutils': 5.0.2_rollup@3.20.1 resolve: 1.22.1 - rollup: 3.20.0 + rollup: 3.20.1 tslib: 2.5.0 typescript: 4.9.3 dev: true - /@rollup/plugin-typescript/11.0.0_rollup@3.20.0+tslib@2.5.0: + /@rollup/plugin-typescript/11.0.0_rollup@3.20.1+tslib@2.5.0: resolution: {integrity: sha512-goPyCWBiimk1iJgSTgsehFD5OOFHiAknrRJjqFCudcW8JtWiBlK284Xnn4flqMqg6YAjVG/EE+3aVzrL5qNSzQ==} engines: {node: '>=14.0.0'} peerDependencies: @@ -3299,13 +3299,13 @@ packages: tslib: optional: true dependencies: - '@rollup/pluginutils': 5.0.2_rollup@3.20.0 + '@rollup/pluginutils': 5.0.2_rollup@3.20.1 resolve: 1.22.1 - rollup: 3.20.0 + rollup: 3.20.1 tslib: 2.5.0 dev: true - /@rollup/pluginutils/5.0.2_rollup@3.20.0: + /@rollup/pluginutils/5.0.2_rollup@3.20.1: resolution: {integrity: sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==} engines: {node: '>=14.0.0'} peerDependencies: @@ -3317,7 +3317,7 @@ packages: '@types/estree': 1.0.0 estree-walker: 2.0.2 picomatch: 2.3.1 - rollup: 3.20.0 + rollup: 3.20.1 dev: true /@rushstack/node-core-library/3.55.2_@types+node@18.15.5: @@ -8540,7 +8540,7 @@ packages: glob: 9.3.1 dev: true - /rollup-plugin-dts/5.2.0_pn5zetjg24cqcolt42iry5qj6a: + /rollup-plugin-dts/5.2.0_4joynb4fart7wudy5do7rdiunu: resolution: {integrity: sha512-B68T/haEu2MKcz4kNUhXB8/h5sq4gpplHAJIYNHbh8cp4ZkvzDvNca/11KQdFrB9ZeKucegQIotzo5T0JUtM8w==} engines: {node: '>=v14'} peerDependencies: @@ -8548,13 +8548,13 @@ packages: typescript: ^4.1 dependencies: magic-string: 0.29.0 - rollup: 3.20.0 + rollup: 3.20.1 typescript: 4.9.5 optionalDependencies: '@babel/code-frame': 7.18.6 dev: true - /rollup-plugin-license/3.0.1_rollup@3.20.0: + /rollup-plugin-license/3.0.1_rollup@3.20.1: resolution: {integrity: sha512-/lec6Y94Y3wMfTDeYTO/jSXII0GQ/XkDZCiqkMKxyU5D5nGPaxr/2JNYvAgYsoCYuOLGOanKDPjCCQiTT96p7A==} engines: {node: '>=14.0.0'} peerDependencies: @@ -8567,13 +8567,13 @@ packages: mkdirp: 1.0.4 moment: 2.29.3 package-name-regex: 2.0.6 - rollup: 3.20.0 + rollup: 3.20.1 spdx-expression-validate: 2.0.0 spdx-satisfies: 5.0.1 dev: true - /rollup/3.20.0: - resolution: {integrity: sha512-YsIfrk80NqUDrxrjWPXUa7PWvAfegZEXHuPsEZg58fGCdjL1I9C1i/NaG+L+27kxxwkrG/QEDEQc8s/ynXWWGQ==} + /rollup/3.20.1: + resolution: {integrity: sha512-sz2w8cBJlWQ2E17RcpvHuf4sk2BQx4tfKDnjNPikEpLEevrbIAR7CH3PGa2hpPwWbNgPaA9yh9Jzljds5bc9zg==} engines: {node: '>=14.18.0', npm: '>=8.0.0'} hasBin: true optionalDependencies: @@ -9483,12 +9483,12 @@ packages: resolution: {integrity: sha512-EK5LeABThyn5KbX0eo5c7xKRQhnHVxKN8/e5Y+YQEf4ZobJB6OZ766756wbVqzIY/G/MvAfLbc6EwFPdSNnlpA==} hasBin: true dependencies: - '@rollup/plugin-alias': 4.0.3_rollup@3.20.0 - '@rollup/plugin-commonjs': 24.0.1_rollup@3.20.0 - '@rollup/plugin-json': 6.0.0_rollup@3.20.0 - '@rollup/plugin-node-resolve': 15.0.1_rollup@3.20.0 - '@rollup/plugin-replace': 5.0.2_rollup@3.20.0 - '@rollup/pluginutils': 5.0.2_rollup@3.20.0 + '@rollup/plugin-alias': 4.0.3_rollup@3.20.1 + '@rollup/plugin-commonjs': 24.0.1_rollup@3.20.1 + '@rollup/plugin-json': 6.0.0_rollup@3.20.1 + '@rollup/plugin-node-resolve': 15.0.1_rollup@3.20.1 + '@rollup/plugin-replace': 5.0.2_rollup@3.20.1 + '@rollup/pluginutils': 5.0.2_rollup@3.20.1 chalk: 5.2.0 consola: 2.15.3 defu: 6.1.2 @@ -9503,8 +9503,8 @@ packages: pathe: 1.1.0 pkg-types: 1.0.2 pretty-bytes: 6.1.0 - rollup: 3.20.0 - rollup-plugin-dts: 5.2.0_pn5zetjg24cqcolt42iry5qj6a + rollup: 3.20.1 + rollup-plugin-dts: 5.2.0_4joynb4fart7wudy5do7rdiunu scule: 1.0.0 typescript: 4.9.5 untyped: 1.2.2 From 68466d3b8ebf0f083680a79e696857ae01d99a18 Mon Sep 17 00:00:00 2001 From: ivan Date: Fri, 24 Mar 2023 11:51:25 +0800 Subject: [PATCH 3/4] fix(css): wait for all emit task finished --- packages/vite/src/node/plugins/css.ts | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/packages/vite/src/node/plugins/css.ts b/packages/vite/src/node/plugins/css.ts index f9bc381cfa0aa6..08b07153bbfa94 100644 --- a/packages/vite/src/node/plugins/css.ts +++ b/packages/vite/src/node/plugins/css.ts @@ -318,7 +318,7 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin { let pureCssChunks: Set let emitTasks: Set<{ name: string; emit: () => Promise }> let sortedEmitTasks: { name: string; emit: () => Promise }[] - let emitTaskRunning = false + let emitTaskRunning: Promise | null // when there are multiple rollup outputs and extracting CSS, only emit once, // since output formats have no effect on the generated CSS. @@ -357,7 +357,7 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin { hasEmitted = false emitTasks = new Set<{ name: string; emit: () => Promise }>() sortedEmitTasks = [] - emitTaskRunning = false + emitTaskRunning = null }, async transform(css, id, options) { @@ -592,16 +592,6 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin { }, }) - const runEmitTasks = async () => { - if (emitTaskRunning) { - return - } - emitTaskRunning = true - for (const { emit } of sortedEmitTasks) { - await emit() - } - } - // wait for collecting all emitFile await sortedEmitTasks @@ -612,9 +602,14 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin { ? 1 : -1 }) + emitTaskRunning = (async () => { + for (const { emit } of sortedEmitTasks) { + await emit() + } + })() } - await runEmitTasks() + await emitTaskRunning } else if (!config.build.ssr) { // legacy build and inline css From 94c3e48c9e4ac800d3af820862ca3737cdf8dd2c Mon Sep 17 00:00:00 2001 From: bluwy Date: Tue, 4 Apr 2023 17:55:08 +0800 Subject: [PATCH 4/4] refactor(css): use promise queue to emit sequentially --- packages/vite/src/node/plugins/css.ts | 77 ++++++++++++--------------- 1 file changed, 33 insertions(+), 44 deletions(-) diff --git a/packages/vite/src/node/plugins/css.ts b/packages/vite/src/node/plugins/css.ts index 08b07153bbfa94..03c7d054890d28 100644 --- a/packages/vite/src/node/plugins/css.ts +++ b/packages/vite/src/node/plugins/css.ts @@ -315,10 +315,9 @@ export function cssPlugin(config: ResolvedConfig): Plugin { export function cssPostPlugin(config: ResolvedConfig): Plugin { // styles initialization in buildStart causes a styling loss in watch const styles: Map = new Map() + // list of css emit tasks to guarantee the files are emitted in a deterministic order + let emitTasks: Promise[] = [] let pureCssChunks: Set - let emitTasks: Set<{ name: string; emit: () => Promise }> - let sortedEmitTasks: { name: string; emit: () => Promise }[] - let emitTaskRunning: Promise | null // when there are multiple rollup outputs and extracting CSS, only emit once, // since output formats have no effect on the generated CSS. @@ -355,9 +354,7 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin { pureCssChunks = new Set() outputToExtractedCSSMap = new Map() hasEmitted = false - emitTasks = new Set<{ name: string; emit: () => Promise }>() - sortedEmitTasks = [] - emitTaskRunning = null + emitTasks = [] }, async transform(css, id, options) { @@ -568,48 +565,40 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin { const cssFileName = ensureFileExt(cssAssetName, '.css') chunkCSS = resolveAssetUrlsInCss(chunkCSS, cssAssetName) - const emitName = path.basename(cssFileName) - - emitTasks.add({ - name: emitName, - emit: async () => { - chunkCSS = await finalizeCss(chunkCSS, true, config) - - // emit corresponding css file - const referenceId = this.emitFile({ - name: emitName, - type: 'asset', - source: chunkCSS, - }) - const originalName = isPreProcessor(lang) - ? cssAssetName - : cssFileName - const isEntry = chunk.isEntry && isPureCssChunk - generatedAssets - .get(config)! - .set(referenceId, { originalName, isEntry }) - chunk.viteMetadata!.importedCss.add(this.getFileName(referenceId)) - }, + + const previousTask = emitTasks[emitTasks.length - 1] + // finalizeCss is async which makes `emitFile` non-deterministic, so + // we use a `.then` to wait for previous tasks before finishing this + const thisTask = finalizeCss(chunkCSS, true, config).then((css) => { + chunkCSS = css + // make sure the previous task is also finished, this works recursively + return previousTask }) - // wait for collecting all emitFile - await sortedEmitTasks + // push this task so the next task can wait for this one + emitTasks.push(thisTask) + const emitTasksLength = emitTasks.length - if (!sortedEmitTasks.length) { - sortedEmitTasks = Array.from(emitTasks).sort((next, cur) => { - return next.name.length > cur.name.length || - (next.name.length === cur.name.length && next.name > cur.name) - ? 1 - : -1 - }) - emitTaskRunning = (async () => { - for (const { emit } of sortedEmitTasks) { - await emit() - } - })() - } + // wait for this and previous tasks to finish + await thisTask - await emitTaskRunning + // emit corresponding css file + const referenceId = this.emitFile({ + name: path.basename(cssFileName), + type: 'asset', + source: chunkCSS, + }) + const originalName = isPreProcessor(lang) ? cssAssetName : cssFileName + const isEntry = chunk.isEntry && isPureCssChunk + generatedAssets + .get(config)! + .set(referenceId, { originalName, isEntry }) + chunk.viteMetadata!.importedCss.add(this.getFileName(referenceId)) + + if (emitTasksLength === emitTasks.length) { + // this is the last task, clear `emitTasks` to free up memory + emitTasks = [] + } } else if (!config.build.ssr) { // legacy build and inline css