Search code examples
webpacksasstailwind-csscss-modulestree-shaking

Does Tailwind CSS tree-shaking work with @apply rules inside *.scss modules?


It's my understanding that Tailwind CSS will tree-shake to only provide bundled CSS with the classes that I'm using. So in the following example:

<div class="flex flex-row">
</div>

...the final Tailwind bundle would only include:

.flex {
  display: flex;
}
.flex-row {
  flex-direction: row;
}

However, I'm wondering if the @apply rule works the same? So if I instead had:

import styles from 'styles.scss';

export default function Example() {
  return (
    <div className={ styles.flex_row }>
    </div>
  )
}

and...

.flex_row {
  @apply flex flex-row;
}

Would this still tree-shake to give me the minimal bundle of Tailwind classes used?

I've Googled and read through the Tailwind docs, but I haven't been able to turn anything up. I'll see if I can look at the outputted bundle to see if it's evident in there...


Solution

  • Consider defining the rule in a @layer base/components/utilities rule and ensuring Tailwind processes the resulting CSS file after Sass has compiled it. This makes the CSS rule "known" to Tailwind, and thus Tailwind will process and "tree-shake" it.


    As an aside, you may also wish to avoid @apply altogether as recommended by Adam Wathan, creator of Tailwind:

    • https://twitter.com/adamwathan/status/1226511611592085504

      Confession: The apply feature in Tailwind basically only exists to trick people who are put off by long lists of classes into trying the framework.

      You should almost never use it 😬

      Reuse your utility-littered HTML instead.

    • https://twitter.com/adamwathan/status/1559250403547652097

      I can say with absolute certainty that if I started Tailwind CSS over from scratch, there would be no @​apply 😬

      The behavior is outrageously complicated, everyone struggles to build the right mental model of what it's supposed to do, and it encourages bad CSS architecture.