Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf(css): improve postcss config resolve #12484

Merged
merged 3 commits into from Mar 21, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
53 changes: 22 additions & 31 deletions packages/vite/src/node/plugins/css.ts
Expand Up @@ -166,10 +166,10 @@ export const removedPureCssFilesCache = new WeakMap<
Map<string, RenderedChunk>
>()

const postcssConfigCache: Record<
string,
WeakMap<ResolvedConfig, PostCSSConfigResult | null>
> = {}
const postcssConfigCache = new WeakMap<
ResolvedConfig,
PostCSSConfigResult | null | Promise<PostCSSConfigResult | null>
>()

function encodePublicUrlsInCSS(config: ResolvedConfig) {
return config.command === 'build'
Expand All @@ -188,6 +188,9 @@ export function cssPlugin(config: ResolvedConfig): Plugin {
extensions: [],
})

// warm up cache for resolved postcss config
resolvePostcssConfig(config)

return {
name: 'vite:css',

Expand Down Expand Up @@ -803,7 +806,7 @@ async function compileCSS(
const needInlineImport = code.includes('@import')
const hasUrl = cssUrlRE.test(code) || cssImageSetRE.test(code)
const lang = id.match(CSS_LANGS_RE)?.[1] as CssLang | undefined
const postcssConfig = await resolvePostcssConfig(config, getCssDialect(lang))
const postcssConfig = await resolvePostcssConfig(config)
Comment on lines -806 to +809
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dialect option can be removed as it was only separated because sugarss mutates the config to add the sugarss parser. Down the code I've refactored to not mutate the config so we can keep a single cache as before.


// 1. plain css that needs no processing
if (
Expand Down Expand Up @@ -884,14 +887,6 @@ async function compileCSS(
// 3. postcss
const postcssOptions = (postcssConfig && postcssConfig.options) || {}

// for sugarss change parser
if (lang === 'sss') {
postcssOptions.parser = loadPreprocessor(
PostCssDialectLang.sss,
config.root,
)
}

const postcssPlugins =
postcssConfig && postcssConfig.plugins ? postcssConfig.plugins.slice() : []

Expand Down Expand Up @@ -974,6 +969,10 @@ async function compileCSS(
.default(postcssPlugins)
.process(code, {
...postcssOptions,
parser:
lang === 'sss'
? loadPreprocessor(PostCssDialectLang.sss, config.root)
: postcssOptions.parser,
to: source,
from: source,
...(devSourcemap
Expand Down Expand Up @@ -1139,16 +1138,10 @@ interface PostCSSConfigResult {

async function resolvePostcssConfig(
config: ResolvedConfig,
dialect = 'css',
): Promise<PostCSSConfigResult | null> {
postcssConfigCache[dialect] ??= new WeakMap<
ResolvedConfig,
PostCSSConfigResult | null
>()

let result = postcssConfigCache[dialect].get(config)
let result = postcssConfigCache.get(config)
if (result !== undefined) {
return result
return await result
}

// inline postcss config via vite config
Expand All @@ -1164,9 +1157,7 @@ async function resolvePostcssConfig(
} else {
const searchPath =
typeof inlineOptions === 'string' ? inlineOptions : config.root
try {
result = await postcssrc({}, searchPath)
} catch (e) {
result = postcssrc({}, searchPath).catch((e) => {
if (!/No PostCSS Config found/.test(e.message)) {
if (e instanceof Error) {
const { name, message, stack } = e
Expand All @@ -1178,11 +1169,15 @@ async function resolvePostcssConfig(
throw new Error(`Failed to load PostCSS config: ${e}`)
}
}
result = null
}
return null
})
// replace cached promise to result object when finished
result.then((resolved) => {
postcssConfigCache.set(config, resolved)
})
}

postcssConfigCache[dialect].set(config, result)
postcssConfigCache.set(config, result)
bluwy marked this conversation as resolved.
Show resolved Hide resolved
return result
}

Expand Down Expand Up @@ -1977,7 +1972,3 @@ const preProcessors = Object.freeze({
function isPreProcessor(lang: any): lang is PreprocessLang {
return lang && lang in preProcessors
}

function getCssDialect(lang: CssLang | undefined): string {
return lang === 'sss' ? 'sss' : 'css'
}