Skip to content

Commit 30194fa

Browse files
sapphi-redbluwy
andauthored
perf(css): only run postcss when needed (#19061)
Co-authored-by: Bjorn Lu <[email protected]>
1 parent 1992f68 commit 30194fa

File tree

2 files changed

+44
-36
lines changed

2 files changed

+44
-36
lines changed

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

+40-32
Original file line numberDiff line numberDiff line change
@@ -1275,7 +1275,6 @@ async function compileCSS(
12751275
): Promise<{
12761276
code: string
12771277
map?: SourceMapInput
1278-
ast?: PostCSS.Result
12791278
modules?: Record<string, string>
12801279
deps?: Set<string>
12811280
}> {
@@ -1284,51 +1283,49 @@ async function compileCSS(
12841283
return compileLightningCSS(id, code, environment, urlResolver)
12851284
}
12861285

1286+
const lang = CSS_LANGS_RE.exec(id)?.[1] as CssLang | undefined
1287+
const deps = new Set<string>()
1288+
1289+
// pre-processors: sass etc.
1290+
let preprocessorMap: ExistingRawSourceMap | undefined
1291+
if (isPreProcessor(lang)) {
1292+
const preprocessorResult = await compileCSSPreprocessors(
1293+
environment,
1294+
id,
1295+
lang,
1296+
code,
1297+
workerController,
1298+
)
1299+
code = preprocessorResult.code
1300+
preprocessorMap = preprocessorResult.map
1301+
preprocessorResult.deps?.forEach((dep) => deps.add(dep))
1302+
}
1303+
12871304
const { modules: modulesOptions, devSourcemap } = config.css
12881305
const isModule = modulesOptions !== false && cssModuleRE.test(id)
12891306
// although at serve time it can work without processing, we do need to
12901307
// crawl them in order to register watch dependencies.
12911308
const needInlineImport = code.includes('@import')
12921309
const hasUrl = cssUrlRE.test(code) || cssImageSetRE.test(code)
1293-
const lang = CSS_LANGS_RE.exec(id)?.[1] as CssLang | undefined
12941310
const postcssConfig = await resolvePostcssConfig(
12951311
environment.getTopLevelConfig(),
12961312
)
12971313

1298-
// 1. plain css that needs no processing
1314+
// postcss processing is not needed
12991315
if (
1300-
lang === 'css' &&
1316+
lang !== 'sss' &&
13011317
!postcssConfig &&
13021318
!isModule &&
13031319
!needInlineImport &&
13041320
!hasUrl
13051321
) {
1306-
return { code, map: null }
1307-
}
1308-
1309-
let modules: Record<string, string> | undefined
1310-
const deps = new Set<string>()
1311-
1312-
// 2. pre-processors: sass etc.
1313-
let preprocessorMap: ExistingRawSourceMap | undefined
1314-
if (isPreProcessor(lang)) {
1315-
const preprocessorResult = await compileCSSPreprocessors(
1316-
environment,
1317-
id,
1318-
lang,
1319-
code,
1320-
workerController,
1321-
)
1322-
code = preprocessorResult.code
1323-
preprocessorMap = preprocessorResult.map
1324-
preprocessorResult.deps?.forEach((dep) => deps.add(dep))
1322+
return { code, map: preprocessorMap ?? null, deps }
13251323
}
13261324

1327-
// 3. postcss
1325+
// postcss
13281326
const atImportResolvers = getAtImportResolvers(
13291327
environment.getTopLevelConfig(),
13301328
)
1331-
const postcssOptions = postcssConfig?.options ?? {}
13321329
const postcssPlugins = postcssConfig?.plugins.slice() ?? []
13331330

13341331
if (needInlineImport) {
@@ -1390,7 +1387,13 @@ async function compileCSS(
13901387
)
13911388
}
13921389

1393-
if (urlResolver) {
1390+
if (
1391+
urlResolver &&
1392+
// if there's an @import, we need to add this plugin
1393+
// regradless of whether it contains url() or image-set(),
1394+
// because we don't know the content referenced by @import
1395+
(needInlineImport || hasUrl)
1396+
) {
13941397
postcssPlugins.push(
13951398
UrlRewritePostcssPlugin({
13961399
resolver: urlResolver,
@@ -1400,6 +1403,8 @@ async function compileCSS(
14001403
)
14011404
}
14021405

1406+
let modules: Record<string, string> | undefined
1407+
14031408
if (isModule) {
14041409
postcssPlugins.unshift(
14051410
(await importPostcssModules()).default({
@@ -1433,7 +1438,11 @@ async function compileCSS(
14331438
)
14341439
}
14351440

1436-
if (!postcssPlugins.length) {
1441+
const postcssOptions = postcssConfig?.options ?? {}
1442+
const postcssParser =
1443+
lang === 'sss' ? loadSss(config.root) : postcssOptions.parser
1444+
1445+
if (!postcssPlugins.length && !postcssParser) {
14371446
return {
14381447
code,
14391448
map: preprocessorMap,
@@ -1445,10 +1454,11 @@ async function compileCSS(
14451454
try {
14461455
const source = removeDirectQuery(id)
14471456
const postcss = await importPostcss()
1457+
14481458
// postcss is an unbundled dep and should be lazy imported
14491459
postcssResult = await postcss.default(postcssPlugins).process(code, {
14501460
...postcssOptions,
1451-
parser: lang === 'sss' ? loadSss(config.root) : postcssOptions.parser,
1461+
parser: postcssParser,
14521462
to: source,
14531463
from: source,
14541464
...(devSourcemap
@@ -1514,7 +1524,6 @@ async function compileCSS(
15141524

15151525
if (!devSourcemap) {
15161526
return {
1517-
ast: postcssResult,
15181527
code: postcssResult.css,
15191528
map: { mappings: '' },
15201529
modules,
@@ -1532,7 +1541,6 @@ async function compileCSS(
15321541
)
15331542

15341543
return {
1535-
ast: postcssResult,
15361544
code: postcssResult.css,
15371545
map: combineSourcemapsIfExists(cleanUrl(id), postcssMap, preprocessorMap),
15381546
modules,
@@ -2182,8 +2190,8 @@ function loadSassPackage(root: string): {
21822190
}
21832191
}
21842192

2185-
let cachedSss: any
2186-
function loadSss(root: string) {
2193+
let cachedSss: PostCSS.Syntax
2194+
function loadSss(root: string): PostCSS.Syntax {
21872195
if (cachedSss) return cachedSss
21882196

21892197
const sssPath = loadPreprocessorPath(PostCssDialectLang.sss, root)

playground/css-sourcemap/__tests__/css-sourcemap.spec.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,8 @@ describe.runIf(isServe)('serve', () => {
138138
const map = extractSourcemap(css)
139139
expect(formatSourcemapForSnapshot(map)).toMatchInlineSnapshot(`
140140
{
141-
"ignoreList": [],
142-
"mappings": "AAGE;EACE,UCJM",
141+
"mappings": "AAGE;EACE,OCJM",
142+
"sourceRoot": "",
143143
"sources": [
144144
"/root/imported.sass",
145145
"/root/imported-nested.sass",
@@ -186,7 +186,7 @@ describe.runIf(isServe)('serve', () => {
186186
expect(formatSourcemapForSnapshot(map)).toMatchInlineSnapshot(`
187187
{
188188
"ignoreList": [],
189-
"mappings": "AACE;EACE",
189+
"mappings": "AACE,SAAC;EACC",
190190
"sources": [
191191
"/root/imported.less",
192192
],
@@ -209,7 +209,7 @@ describe.runIf(isServe)('serve', () => {
209209
expect(formatSourcemapForSnapshot(map)).toMatchInlineSnapshot(`
210210
{
211211
"ignoreList": [],
212-
"mappings": "AACE;EACE,cAAM",
212+
"mappings": "AACE;EACE,OAAM,QAAN",
213213
"sources": [
214214
"/root/imported.styl",
215215
],

0 commit comments

Comments
 (0)