diff --git a/CHANGELOG.md b/CHANGELOG.md index 12b3648a088e..a9265922bc08 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Don't prefix arbitrary classes in `group` and `peer` variants ([#11454](https://github.com/tailwindlabs/tailwindcss/pull/11454)) - Sort classes using position of first matching rule ([#11504](https://github.com/tailwindlabs/tailwindcss/pull/11504)) - Bump `jiti`, `lightningcss`, `fast-glob` and `browserlist` dependencies and reflect `lightningcss` related improvements in tests ([#11550](https://github.com/tailwindlabs/tailwindcss/pull/11550)) +- Make PostCSS plugin async to improve performance ([#11548](https://github.com/tailwindlabs/tailwindcss/pull/11548)) ### Added diff --git a/src/cli/build/plugin.js b/src/cli/build/plugin.js index 784260324a5b..a82343f10db5 100644 --- a/src/cli/build/plugin.js +++ b/src/cli/build/plugin.js @@ -294,9 +294,9 @@ export async function createProcessor(args, cliConfigPath) { let tailwindPlugin = () => { return { postcssPlugin: 'tailwindcss', - Once(root, { result }) { + async Once(root, { result }) { env.DEBUG && console.time('Compiling CSS') - tailwind(({ createContext }) => { + await tailwind(({ createContext }) => { console.error() console.error('Rebuilding...') diff --git a/src/lib/expandTailwindAtRules.js b/src/lib/expandTailwindAtRules.js index 5f4391a150e0..b9b54bd6219e 100644 --- a/src/lib/expandTailwindAtRules.js +++ b/src/lib/expandTailwindAtRules.js @@ -103,7 +103,7 @@ function buildStylesheet(rules, context) { } export default function expandTailwindAtRules(context) { - return (root) => { + return async (root) => { let layerNodes = { base: null, components: null, @@ -160,18 +160,22 @@ export default function expandTailwindAtRules(context) { } if (regexParserContent.length > 0) { - for (let [{ file, content }, { transformer, extractor }] of regexParserContent) { - content = file ? fs.readFileSync(file, 'utf8') : content - getClassCandidates(transformer(content), extractor, candidates, seen) - } + await Promise.all( + regexParserContent.map(async ([{ file, content }, { transformer, extractor }]) => { + content = file ? await fs.promises.readFile(file, 'utf8') : content + getClassCandidates(transformer(content), extractor, candidates, seen) + }) + ) } } else { - for (let { file, content, extension } of context.changedContent) { - let transformer = getTransformer(context.tailwindConfig, extension) - let extractor = getExtractor(context, extension) - content = file ? fs.readFileSync(file, 'utf8') : content - getClassCandidates(transformer(content), extractor, candidates, seen) - } + await Promise.all( + context.changedContent.map(async ({ file, content, extension }) => { + let transformer = getTransformer(context.tailwindConfig, extension) + let extractor = getExtractor(context, extension) + content = file ? await fs.promises.readFile(file, 'utf8') : content + getClassCandidates(transformer(content), extractor, candidates, seen) + }) + ) } env.DEBUG && console.timeEnd('Reading changed files') diff --git a/src/plugin.js b/src/plugin.js index 7f1eff49630c..14fb7f890918 100644 --- a/src/plugin.js +++ b/src/plugin.js @@ -23,7 +23,7 @@ module.exports = function tailwindcss(configOrPath) { return root }, ...handleImportAtRules(), - function (root, result) { + async function (root, result) { // Use the path for the `@config` directive if it exists, otherwise use the // path for the file being processed configOrPath = findAtConfigPath(root, result) ?? configOrPath @@ -42,7 +42,7 @@ module.exports = function tailwindcss(configOrPath) { return } - processTailwindFeatures(context)(root, result) + await processTailwindFeatures(context)(root, result) }, function lightningCssPlugin(_root, result) { let map = result.map ?? result.opts.map diff --git a/src/processTailwindFeatures.js b/src/processTailwindFeatures.js index 952e17a13762..fa363b003bf2 100644 --- a/src/processTailwindFeatures.js +++ b/src/processTailwindFeatures.js @@ -12,7 +12,7 @@ import { createContext } from './lib/setupContextUtils' import { issueFlagNotices } from './featureFlags' export default function processTailwindFeatures(setupContext) { - return function (root, result) { + return async function (root, result) { let { tailwindDirectives, applyDirectives } = normalizeTailwindDirectives(root) detectNesting()(root, result) @@ -44,7 +44,8 @@ export default function processTailwindFeatures(setupContext) { issueFlagNotices(context.tailwindConfig) - expandTailwindAtRules(context)(root, result) + await expandTailwindAtRules(context)(root, result) + // Partition apply rules that are generated by // addComponents, addUtilities and so on. partitionApplyAtRules()(root, result)