Trying to use Tailwind with Webpack and css-loader, modules turned on; doesn't seem to work.
All Tailwind classes become localised. The following doesn't work:
:global {
@tailwind preflight;
@tailwind utilities;
}
Currently using a workaround by including Tailwind inside of a separate file (and hence a separate rule), but it'd be nice if this could be addressed somehow.
Can you share an example project with everything setup the way you'd like? I haven't really used CSS Modules at all so unsure what I should be testing or trying to get working. If you can share a test repo, I can see if it's solvable.
Sure thing. https://github.com/parkroolucas/tailwind-cssmodules
A quick npm i && npm run watch should get the code running at 8080.
Alright figured this out although I barely understand how this was the problem...
You need to use the @tailwind screens directive to control where Tailwind generates it's media queries. Right now, they are being appended to the end of the stylesheet by default since there's no explicit rendering location, and that's making things blow up.
Try this:
:global {
@tailwind preflight;
@tailwind utilities;
@tailwind screens;
}
I tried doing exactly that inside of the tailwind-cssmodules repo I created, but to no avail. I changed main.scss to the following:
:global {
@tailwind preflight;
@tailwind utilities;
@tailwind screens;
}
Didn't seem to help though. Is there anything else on your side that I need in order to get this working?
Ah you know what you're right, I had something commented out in the config. So still can't figure this out. I have no idea what Tailwind could really do differently here, all it does is replace those directives with a bunch of classes, so I'm not sure what is instructing the rest of the build to change the names of all of them :/
How does CSS Modules actually work? When does it run and against what input? What even causes it to run, is it this line?
'css-loader?modules&importLoaders=1&localIdentName=[name]_[local]_[hash:base64:5]',
Does the order of these loaders matter? Is there any way to configure this to do all of the Tailwind stuff first, and only do all of the CSS Modules stuff after Tailwind is completely done so that CSS Modules can't even tell that the code was generated by Tailwind and not just typed by hand in the :global block?
Ah reading the documentation I think I see what's happening:
https://github.com/css-modules/css-modules#usage-with-preprocessors
The :global block is a preprocessor feature, which means that block is parsed and replaced before Tailwind ever runs, since that block is processed by Sass and Tailwind runs way later in the PostCSS phase.
It seems like to use global styles without a preprocessor, you need to use syntax like:
:global(.foo) {
...
}
...at the per-selector level.
Not sure what the best solution is here unfortunately :/ I don't have any plans to add configuration to Tailwind to generate stuff this way unless absolutely 100% necessary; feels to me like something that should be handled by the build process.
Maybe some ideas here on how to use multiple loaders with Webpack to process a separate file of Tailwind styles without it running through CSS Modules:
https://stackoverflow.com/questions/35398733/css-modules-how-do-i-disable-local-scope-for-a-file
The issue is really that when SASS works out the nesting postcss didnt ran yet, so it's output is:
:global {
@tailwind preflight;
@tailwind utilities;
}
PostCSS does it's job well actually after that, it will outputs the tailwind css inside the :global block and keeps the block intact, but css-loader actually can't work with this syntax, it expects the :global in the selector, like so:
:global .foo {}
:global .bar {}
:global .baz {}
You could ofcourse change the order of the loaders and run postcss before sass (the order is backwards in webpack's loader array), but that will likely have other consequences.
If you only need nesting, then you could ditch sass and use other postcss plugins too.
So it sounds like one solution then might be another PostCSS plugin that looks for :global blocks with no trailing selectors and prefixes all of them, before CSS Modules runs against the output. Maybe that exists already?
Tried it on @parkroolucas example repo, running postcss-nested after tailwind seems to fix the issue, you still need to @tailwind screens; though.
@tlgreg that solved it. Thanks for the help guys!
Most helpful comment
Tried it on @parkroolucas example repo, running postcss-nested after tailwind seems to fix the issue, you still need to
@tailwind screens;though.