From b69fe002e3c0ea9660b67475a99f3451c9040feb Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Tue, 17 Sep 2024 19:08:49 +0900 Subject: [PATCH 1/2] fix(css): fix sass compiler double initialization race condition --- packages/vite/src/node/plugins/css.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/vite/src/node/plugins/css.ts b/packages/vite/src/node/plugins/css.ts index 390804543ce9e3..f2d8cd440cb2bc 100644 --- a/packages/vite/src/node/plugins/css.ts +++ b/packages/vite/src/node/plugins/css.ts @@ -2350,7 +2350,7 @@ const makeModernCompilerScssWorker = ( alias: Alias[], _maxWorkers: number | undefined, ) => { - let compiler: Sass.AsyncCompiler | undefined + let compilerPromise: Promise | undefined const worker: Awaited> = { async run(sassPath, data, options) { @@ -2358,7 +2358,8 @@ const makeModernCompilerScssWorker = ( // https://github.com/nodejs/node/issues/31710 const sass: typeof Sass = (await import(pathToFileURL(sassPath).href)) .default - compiler ??= await sass.initAsyncCompiler() + compilerPromise ??= sass.initAsyncCompiler() + const compiler = await compilerPromise const sassOptions = { ...options } as Sass.StringOptions<'async'> sassOptions.url = pathToFileURL(options.filename) @@ -2414,8 +2415,8 @@ const makeModernCompilerScssWorker = ( } satisfies ScssWorkerResult }, async stop() { - compiler?.dispose() - compiler = undefined + ;(await compilerPromise)?.dispose() + compilerPromise = undefined }, } From 44b6edecd51aa77827090adc5e2d3348614d830d Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Wed, 18 Sep 2024 09:37:13 +0900 Subject: [PATCH 2/2] test: add test --- .../sass-modern-compiler.spec.ts | 15 +++++++++++ .../sass-modern-compiler-build/entry1.scss | 3 +++ .../sass-modern-compiler-build/entry2.scss | 3 +++ .../vite.config-sass-modern-compiler-build.js | 27 +++++++++++++++++++ 4 files changed, 48 insertions(+) create mode 100644 playground/css/__tests__/sass-modern-compiler-build/sass-modern-compiler.spec.ts create mode 100644 playground/css/sass-modern-compiler-build/entry1.scss create mode 100644 playground/css/sass-modern-compiler-build/entry2.scss create mode 100644 playground/css/vite.config-sass-modern-compiler-build.js diff --git a/playground/css/__tests__/sass-modern-compiler-build/sass-modern-compiler.spec.ts b/playground/css/__tests__/sass-modern-compiler-build/sass-modern-compiler.spec.ts new file mode 100644 index 00000000000000..98bba744b175d5 --- /dev/null +++ b/playground/css/__tests__/sass-modern-compiler-build/sass-modern-compiler.spec.ts @@ -0,0 +1,15 @@ +import { expect, test } from 'vitest' +import { findAssetFile, isBuild } from '~utils' + +test.runIf(isBuild)('sass modern compiler build multiple entries', () => { + expect(findAssetFile(/entry1/, 'sass-modern-compiler-build')) + .toMatchInlineSnapshot(` + ".entry1{color:red} + " + `) + expect(findAssetFile(/entry2/, 'sass-modern-compiler-build')) + .toMatchInlineSnapshot(` + ".entry2{color:#00f} + " + `) +}) diff --git a/playground/css/sass-modern-compiler-build/entry1.scss b/playground/css/sass-modern-compiler-build/entry1.scss new file mode 100644 index 00000000000000..e21334eb8337bc --- /dev/null +++ b/playground/css/sass-modern-compiler-build/entry1.scss @@ -0,0 +1,3 @@ +.entry1 { + color: red; +} diff --git a/playground/css/sass-modern-compiler-build/entry2.scss b/playground/css/sass-modern-compiler-build/entry2.scss new file mode 100644 index 00000000000000..eca3004c9d247f --- /dev/null +++ b/playground/css/sass-modern-compiler-build/entry2.scss @@ -0,0 +1,3 @@ +.entry2 { + color: blue; +} diff --git a/playground/css/vite.config-sass-modern-compiler-build.js b/playground/css/vite.config-sass-modern-compiler-build.js new file mode 100644 index 00000000000000..b44ef1e354d4d9 --- /dev/null +++ b/playground/css/vite.config-sass-modern-compiler-build.js @@ -0,0 +1,27 @@ +import path from 'node:path' +import { defineConfig } from 'vite' + +export default defineConfig({ + build: { + outDir: 'dist/sass-modern-compiler-build', + rollupOptions: { + input: { + entry1: path.join( + import.meta.dirname, + 'sass-modern-compiler-build/entry1.scss', + ), + entry2: path.join( + import.meta.dirname, + 'sass-modern-compiler-build/entry2.scss', + ), + }, + }, + }, + css: { + preprocessorOptions: { + scss: { + api: 'modern-compiler', + }, + }, + }, +})