Double generation of CSS class names (Next.JS + Tailwind)
gggglglglg opened this issue ยท 3 comments
Hi
I use Tailwind with the prefix tw-
In next.config.js
:
reactStrictMode: false,
...
if (!dev) {
const MangleCssClassPlugin = require('mangle-css-class-webpack-plugin')
config.plugins.push(
new MangleCssClassPlugin({
classNameRegExp: '((hover|focus|active|disabled|visited|first|last|odd|even|group-hover|focus-within|xs|sm|md|lg|xl)[\\\\]*:)*tw-[a-zA-Z0-9_-]*([\\\\]*\/[0-9]*)?',
ignorePrefixRegExp: '((hover|focus|active|disabled|visited|first|last|odd|even|group-hover|focus-within|xs|sm|md||lg|xl)[\\\\]*:)*',
log: true,
})
)
}
When I run a build, the css file gets double class names (check tw-py-8
)
Minify class name from tw-font-body to d
Minify class name from tw-py-8 to e
Skip the prefix md: of md:tw-py-12
Minify class name from tw-py-12 to f
...
Minify class name from tw-py-8 to ya
As we see the tw-py-8 class is processed twice (E
and YA
)
So the css file
looks like this (for tw-py-8
):
.e {
left:50%
}
.ya {
padding-top:2rem;
padding-bottom:2rem
}
As we see the YA
class is correct (for tailwind tw-py-8
)
BUT
The class E
is inserted in the page
As a result, the entire design does not display correctly
Any idea?
PS:
Next.js last version
Tailwind last version
It seems the problem is the server side rendering vs client side rendering. Fix would be a custom classGenerator.
i tried this
// next.config.js
webpack(config, { dev, nextRuntime }) {
...
console.log('webpack ran, nextRuntime :', nextRuntime )
...
}
and it ran 3 times, which is probably the problem. one for edge, nodejs, and undefined (client). i tried some different scenarios so webpack only ran once. i checked the and went to the autogenerated css
client
// next.config.js
...
if (!dev && typeof nextRuntime === 'undefined') {
config.plugins.push(
new MangleCssClassPlugin({
// settings
)}
)
}
only the autogenerated css file classnames changed, but not the html classnames
then i tried with nodejs
// next.config.js
...
if (!dev && nextRuntime === 'nodejs') {
config.plugins.push(
new MangleCssClassPlugin({
// settings
)}
)
}
only the html classnames and not the autogenerated css file classnames
i think the problem is that the different runtimes generate different classnames but we need both because one generates the html classnames and one is required to generate the css file classnames
best solution would be for a custom classgenerator so the client and server have consistent classnames
try something like
classGenerator: original => btoa(original).replace(/=/g, '')
this will ensure the classnames are consistent and unqiue and removes the equal signs which break the css
hope this helpful
@ermaxinc @frog1123 Release the new version(5.0.9) which may fix the issue. Could you check if it works?
Here it makes the ClassGenerator Instance singleton.
3eeffce#diff-cd079ac25597bb2b0b25c925d8be0ad595d5aaacea6b023c3df55e5795c87b3cR87