From 643d1529d7427a501b85869ad947bd61d76c55d8 Mon Sep 17 00:00:00 2001 From: sapphi-red <49056869+sapphi-red@users.noreply.github.com> Date: Tue, 24 Dec 2024 19:17:37 +0900 Subject: [PATCH 1/4] perf: only run postcss when needed --- packages/vite/src/node/plugins/css.ts | 63 ++++++++++--------- .../__tests__/css-sourcemap.spec.ts | 8 +-- 2 files changed, 38 insertions(+), 33 deletions(-) diff --git a/packages/vite/src/node/plugins/css.ts b/packages/vite/src/node/plugins/css.ts index 46db13a0f15f51..9a13e981fa01c8 100644 --- a/packages/vite/src/node/plugins/css.ts +++ b/packages/vite/src/node/plugins/css.ts @@ -1271,7 +1271,6 @@ async function compileCSS( ): Promise<{ code: string map?: SourceMapInput - ast?: PostCSS.Result modules?: Record deps?: Set }> { @@ -1280,51 +1279,49 @@ async function compileCSS( return compileLightningCSS(id, code, environment, urlReplacer) } + const lang = CSS_LANGS_RE.exec(id)?.[1] as CssLang | undefined + const deps = new Set() + + // pre-processors: sass etc. + let preprocessorMap: ExistingRawSourceMap | undefined + if (isPreProcessor(lang)) { + const preprocessorResult = await compileCSSPreprocessors( + environment, + id, + lang, + code, + workerController, + ) + code = preprocessorResult.code + preprocessorMap = preprocessorResult.map + preprocessorResult.deps?.forEach((dep) => deps.add(dep)) + } + const { modules: modulesOptions, devSourcemap } = config.css const isModule = modulesOptions !== false && cssModuleRE.test(id) // although at serve time it can work without processing, we do need to // crawl them in order to register watch dependencies. const needInlineImport = code.includes('@import') const hasUrl = cssUrlRE.test(code) || cssImageSetRE.test(code) - const lang = CSS_LANGS_RE.exec(id)?.[1] as CssLang | undefined const postcssConfig = await resolvePostcssConfig( environment.getTopLevelConfig(), ) - // 1. plain css that needs no processing + // postcss processing is not needed if ( - lang === 'css' && + lang !== 'sss' && !postcssConfig && !isModule && !needInlineImport && !hasUrl ) { - return { code, map: null } + return { code, map: preprocessorMap ?? null, deps } } - let modules: Record | undefined - const deps = new Set() - - // 2. pre-processors: sass etc. - let preprocessorMap: ExistingRawSourceMap | undefined - if (isPreProcessor(lang)) { - const preprocessorResult = await compileCSSPreprocessors( - environment, - id, - lang, - code, - workerController, - ) - code = preprocessorResult.code - preprocessorMap = preprocessorResult.map - preprocessorResult.deps?.forEach((dep) => deps.add(dep)) - } - - // 3. postcss + // postcss const atImportResolvers = getAtImportResolvers( environment.getTopLevelConfig(), ) - const postcssOptions = postcssConfig?.options ?? {} const postcssPlugins = postcssConfig?.plugins.slice() ?? [] if (needInlineImport) { @@ -1386,7 +1383,13 @@ async function compileCSS( ) } - if (urlReplacer) { + if ( + urlReplacer && + // if there's an @import, we need to add this plugin + // regradless of whether it contains url() or image-set(), + // because we don't know the content referenced by @import + (needInlineImport || cssUrlRE.test(code) || cssImageSetRE.test(code)) + ) { postcssPlugins.push( UrlRewritePostcssPlugin({ replacer: urlReplacer, @@ -1395,6 +1398,8 @@ async function compileCSS( ) } + let modules: Record | undefined + if (isModule) { postcssPlugins.unshift( (await importPostcssModules()).default({ @@ -1428,7 +1433,7 @@ async function compileCSS( ) } - if (!postcssPlugins.length) { + if (lang !== 'sss' && !postcssPlugins.length) { return { code, map: preprocessorMap, @@ -1440,6 +1445,8 @@ async function compileCSS( try { const source = removeDirectQuery(id) const postcss = await importPostcss() + const postcssOptions = postcssConfig?.options ?? {} + // postcss is an unbundled dep and should be lazy imported postcssResult = await postcss.default(postcssPlugins).process(code, { ...postcssOptions, @@ -1509,7 +1516,6 @@ async function compileCSS( if (!devSourcemap) { return { - ast: postcssResult, code: postcssResult.css, map: { mappings: '' }, modules, @@ -1527,7 +1533,6 @@ async function compileCSS( ) return { - ast: postcssResult, code: postcssResult.css, map: combineSourcemapsIfExists(cleanUrl(id), postcssMap, preprocessorMap), modules, diff --git a/playground/css-sourcemap/__tests__/css-sourcemap.spec.ts b/playground/css-sourcemap/__tests__/css-sourcemap.spec.ts index 40bef704173384..f943143187ee51 100644 --- a/playground/css-sourcemap/__tests__/css-sourcemap.spec.ts +++ b/playground/css-sourcemap/__tests__/css-sourcemap.spec.ts @@ -138,8 +138,8 @@ describe.runIf(isServe)('serve', () => { const map = extractSourcemap(css) expect(formatSourcemapForSnapshot(map)).toMatchInlineSnapshot(` { - "ignoreList": [], - "mappings": "AAGE;EACE,UCJM", + "mappings": "AAGE;EACE,OCJM", + "sourceRoot": "", "sources": [ "/root/imported.sass", "/root/imported-nested.sass", @@ -186,7 +186,7 @@ describe.runIf(isServe)('serve', () => { expect(formatSourcemapForSnapshot(map)).toMatchInlineSnapshot(` { "ignoreList": [], - "mappings": "AACE;EACE", + "mappings": "AACE,SAAC;EACC", "sources": [ "/root/imported.less", ], @@ -209,7 +209,7 @@ describe.runIf(isServe)('serve', () => { expect(formatSourcemapForSnapshot(map)).toMatchInlineSnapshot(` { "ignoreList": [], - "mappings": "AACE;EACE,cAAM", + "mappings": "AACE;EACE,OAAM,QAAN", "sources": [ "/root/imported.styl", ], From 76e3da4d85e9d2bb5849e40cb621de3aa673c715 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BF=A0=20/=20green?= Date: Tue, 7 Jan 2025 17:27:10 +0900 Subject: [PATCH 2/4] refactor: use `hasUrl` Co-authored-by: Bjorn Lu --- packages/vite/src/node/plugins/css.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vite/src/node/plugins/css.ts b/packages/vite/src/node/plugins/css.ts index 530173eef545cb..bd0f135fde7076 100644 --- a/packages/vite/src/node/plugins/css.ts +++ b/packages/vite/src/node/plugins/css.ts @@ -1389,7 +1389,7 @@ async function compileCSS( // if there's an @import, we need to add this plugin // regradless of whether it contains url() or image-set(), // because we don't know the content referenced by @import - (needInlineImport || cssUrlRE.test(code) || cssImageSetRE.test(code)) + (needInlineImport || hasUrl) ) { postcssPlugins.push( UrlRewritePostcssPlugin({ From f177476232968889391e1037b6c4fb7030eb1ccc Mon Sep 17 00:00:00 2001 From: sapphi-red <49056869+sapphi-red@users.noreply.github.com> Date: Tue, 7 Jan 2025 17:33:14 +0900 Subject: [PATCH 3/4] refactor: check for parser --- packages/vite/src/node/plugins/css.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/packages/vite/src/node/plugins/css.ts b/packages/vite/src/node/plugins/css.ts index bd0f135fde7076..955350139ea325 100644 --- a/packages/vite/src/node/plugins/css.ts +++ b/packages/vite/src/node/plugins/css.ts @@ -1434,7 +1434,11 @@ async function compileCSS( ) } - if (lang !== 'sss' && !postcssPlugins.length) { + const postcssOptions = postcssConfig?.options ?? {} + const postcssParser = + lang === 'sss' ? loadSss(config.root) : postcssOptions.parser + + if (!postcssPlugins.length && !postcssParser) { return { code, map: preprocessorMap, @@ -1446,12 +1450,11 @@ async function compileCSS( try { const source = removeDirectQuery(id) const postcss = await importPostcss() - const postcssOptions = postcssConfig?.options ?? {} // postcss is an unbundled dep and should be lazy imported postcssResult = await postcss.default(postcssPlugins).process(code, { ...postcssOptions, - parser: lang === 'sss' ? loadSss(config.root) : postcssOptions.parser, + parser: postcssParser, to: source, from: source, ...(devSourcemap @@ -2156,7 +2159,7 @@ function loadSassPackage(root: string): { } let cachedSss: any -function loadSss(root: string) { +function loadSss(root: string): PostCSS.Syntax { if (cachedSss) return cachedSss const sssPath = loadPreprocessorPath(PostCssDialectLang.sss, root) From a1394bf224a7afcdeddab8262d8b9eafb338de82 Mon Sep 17 00:00:00 2001 From: sapphi-red <49056869+sapphi-red@users.noreply.github.com> Date: Tue, 7 Jan 2025 17:44:59 +0900 Subject: [PATCH 4/4] refactor: add type --- packages/vite/src/node/plugins/css.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vite/src/node/plugins/css.ts b/packages/vite/src/node/plugins/css.ts index 955350139ea325..2935100638a059 100644 --- a/packages/vite/src/node/plugins/css.ts +++ b/packages/vite/src/node/plugins/css.ts @@ -2158,7 +2158,7 @@ function loadSassPackage(root: string): { } } -let cachedSss: any +let cachedSss: PostCSS.Syntax function loadSss(root: string): PostCSS.Syntax { if (cachedSss) return cachedSss