@@ -11,15 +11,25 @@ import substituteScreenAtRules from './substituteScreenAtRules'
1111import prefixSelector from '../util/prefixSelector'
1212import { useMemo } from '../util/useMemo'
1313
14- function hasAtRule ( css , atRule ) {
15- let foundAtRule = false
16-
17- css . walkAtRules ( atRule , ( ) => {
18- foundAtRule = true
19- return false
20- } )
14+ function hasAtRule ( css , atRule , condition ) {
15+ let found = false
16+
17+ css . walkAtRules (
18+ atRule ,
19+ condition === undefined
20+ ? ( ) => {
21+ found = true
22+ return false
23+ }
24+ : ( node ) => {
25+ if ( condition ( node ) ) {
26+ found = true
27+ return false
28+ }
29+ }
30+ )
2131
22- return foundAtRule
32+ return found
2333}
2434
2535function cloneWithoutChildren ( node ) {
@@ -298,7 +308,7 @@ function processApplyAtRules(css, lookupTree, config) {
298308 return css
299309}
300310
301- let defaultTailwindTree = null
311+ let defaultTailwindTree = new Map ( )
302312
303313export default function substituteClassApplyAtRules ( config , getProcessedPlugins , configChanged ) {
304314 return function ( css ) {
@@ -307,15 +317,29 @@ export default function substituteClassApplyAtRules(config, getProcessedPlugins,
307317 return css
308318 }
309319
310- // Tree already contains @tailwind rules, don't prepend default Tailwind tree
311- if ( hasAtRule ( css , 'tailwind' ) ) {
320+ let requiredTailwindAtRules = [ 'base' , 'components' , 'utilities' ]
321+ if (
322+ hasAtRule ( css , 'tailwind' , ( node ) => {
323+ let idx = requiredTailwindAtRules . indexOf ( node . params )
324+ if ( idx !== - 1 ) requiredTailwindAtRules . splice ( idx , 1 )
325+ if ( requiredTailwindAtRules . length <= 0 ) return true
326+ return false
327+ } )
328+ ) {
329+ // Tree already contains all the at rules (requiredTailwindAtRules)
312330 return processApplyAtRules ( css , postcss . root ( ) , config )
313331 }
314332
315- // Tree contains no @tailwind rules, so generate all of Tailwind's styles and
316- // prepend them to the user's CSS. Important for <style> blocks in Vue components.
333+ let lookupKey = requiredTailwindAtRules . join ( ',' )
334+
335+ // We mutated the `requiredTailwindAtRules`, but when we hit this point in
336+ // time, it means that we don't have all the atrules. The missing atrules
337+ // are listed inside the requiredTailwindAtRules, which we can use to fill
338+ // in the missing pieces.
339+ //
340+ // Important for <style> blocks in Vue components.
317341 const generateLookupTree =
318- configChanged || defaultTailwindTree === null
342+ configChanged || ! defaultTailwindTree . has ( lookupKey )
319343 ? ( ) => {
320344 return postcss ( [
321345 substituteTailwindAtRules ( config , getProcessedPlugins ( ) ) ,
@@ -325,20 +349,15 @@ export default function substituteClassApplyAtRules(config, getProcessedPlugins,
325349 convertLayerAtRulesToControlComments ( config ) ,
326350 substituteScreenAtRules ( config ) ,
327351 ] )
328- . process (
329- `
330- @tailwind base;
331- @tailwind components;
332- @tailwind utilities;
333- ` ,
334- { from : undefined }
335- )
352+ . process ( requiredTailwindAtRules . map ( ( rule ) => `@tailwind ${ rule } ;` ) . join ( '\n' ) , {
353+ from : undefined ,
354+ } )
336355 . then ( ( result ) => {
337- defaultTailwindTree = result
338- return defaultTailwindTree
356+ defaultTailwindTree . set ( lookupKey , result )
357+ return result
339358 } )
340359 }
341- : ( ) => Promise . resolve ( defaultTailwindTree )
360+ : ( ) => Promise . resolve ( defaultTailwindTree . get ( lookupKey ) )
342361
343362 return generateLookupTree ( ) . then ( ( result ) => {
344363 return processApplyAtRules ( css , result . root , config )
0 commit comments