how can I make this plugin support Tailwind screen prefixes ?
vesper8 opened this issue Β· 11 comments
I'm wondering if you could explain how, or if it's even possible, to support Tailwind CSS screen prefixes?
Let me explain, Tailwind lets you set a prefix which is very useful for using with this package. The default prefix is tw-
This is how I configured your plugin right now:
const cssObfuscatorPlugin = new MangleCssClassPlugin({
classNameRegExp: '(tw)-[a-zA-Z0-9_-]*',
log: true,
});
This works great, it converts all the tailwind classes to 2 or 3 character long classes.. perfect
Tailwind CSS also supports prefixes for responsive websites. It has 5 default prefixes: xs,sm,md,lg,xl
So you can write something like this
<div class="tw-p-2 md:tw-p-4">test</div>
Which translates to
on all devices default to padding: 2rem; but on "medium" devices, aka tablet+desktop, use padding: 4rem;
Doing this
const cssObfuscatorPlugin = new MangleCssClassPlugin({
classNameRegExp: '(tw-|xs:tw-|md:tw-|sm:tw-|lg:tw-|xl:tw-|answer-|quiz-)[a-zA-Z0-9_-]*',
log: true,
});
Changes
<div class="tw-p-2 md:tw-p-4">test</div>
to
<div class="aa ab">test</div>
But that breaks the prefix support
What I need it to do is change
<div class="tw-p-2 md:tw-p-4">test</div>
to
<div class="aa md:ab">test</div>
So, converting all classes that begin with tw-
, but leaving the prefixes in place
According go https://regex101.com/r/herNMh/2
(tw)-[a-zA-Z0-9_-]*
should already be matching both tw-p-2 and tw-p-4
in <div class="tw-p-2 md:tw-p-4">test</div>
, but it actually ends up ignoring all of md:tw-p-4
when run through your plugin
It's interesting class name form. Let me try it later.
The option will be:
classNameRegExp: '(xs:|md:|sm:|lg:|xl:)?tw-[a-zA-Z0-9_-]*',
ignorePrefix: ['xs:', 'md:', 'sm:', 'lg:', 'xl:'],
@sndyuk thanks a lot for taking this on! It's very close to working now but there's still a hiccup
With your new change, it did indeed make the correct change in the html, changing
<div class="tw-p-2 md:tw-p-4">test</div>
to
<div class="aa md:ab">test</div>
What is still failing however is that in the generated css bundle, tw-p-2
was indeed changed to aa
But md:tw-p-4
was not changed to md:ab
Instead it remained unchanged and looks like this in the minified app.css bundle: .md\:tw-p-4{padding:1rem}
That's probably my bad for not mentioning the syntax inside the bundle until now. I guess the colon is escaped, or maybe your script isn't taking into account the unique class name composition
Now that I have more clarity into what gets added to the bundle css, I can see that there's two ways to handle this, the prefix doesn't really need to survive into the production html/bundle, it's just that because of the uniqueness of the class composition, it wasn't being caught on both ends
I hope I'm making sense! Would really appreciate it if you could make another modification that will
To make everything clearer I created this demo repository https://github.com/vesper8/vue-cli-tailwind-mangle-css-class-webpack-plugin
If you run yarn install and yarn serve
you'll see the responsiveness in action, then if you run yarn build
and serve the files inside the dist
folder you'll see your plugin in action
@vesper8 Thanks! The demo repository deepened my understanding.
To escape the back slash, use both of bellow:
- For JS:
\\\\\\\\\\\\\\\\
. It's required by development mode. - For CSS:
\\\\
. It's required by production mode.
Also I added the ignorePrefixRegExp
option since the ignorePrefix
option becomes too long to list up the all prefixes.
I guess the option can be used for tailwind. At least the demo works well:
classNameRegExp: '((hover|focus|xs|md|sm|lg|xl)(\\\\\\\\\\\\\\\\|\\\\)?:)*tw-[a-z_-][a-zA-Z0-9_-]*',
ignorePrefixRegExp: '((hover|focus|xs|md|sm|lg|xl)(\\\\\\\\\\\\\\\\|\\\\)?:)*',
Let me know if it works or not.
@sndyuk beautiful!!! once again thanks for your quick work. I have no doubt this will be used by lots of tailwind CSS users now.. might have to promote it a bit as being tailwind-compatible and including these instructions in the guide. I'll pass the word about too.
It works perfectly now for my current use.
And thanks for catching the hover and focus prefixes I had forgotten about those
However, now that I've visited https://tailwindcss.com/docs/pseudo-class-variants/ I see there are multiple other possible prefixes, all of these:
hover:
focus:
active:
disabled:
visited:
first:
last:
odd:
even:
group-hover:
focus-within:
AND, it's possible to combine any of those above with the 5 (xs, sm, md, lg, xl
) responsive prefixes, like so:
sm:hover:tw-text-blue-500
md:visited:tw-text-purple-400
Do you suspect that the script needs further modification to be able to handle this last case?
Lastly, I noticed that class names that include a slash, and there are many such class names (examples https://tailwindcss.com/docs/width), such as .w-2/5
, are being mangled to .hd/5
, which still correctly matches up with .hd\/5{width:40%}
in the generated app.css
So it does work with, but it doesn't shorten/obfuscate the class names quite as much as it could so there's room for more optimization there
@vesper8 This will work for the cases:
a. tw-text
b. tw-text1/5
c. even:tw-text
d. xs:group-hover:even:tw-text-1/5
e. group-hover:xs:even:tw-text-1/5
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)(\\\\\\\\\\\\\\\\|\\\\)?:)*',
It'll be great if you could update README for the tailwind CSS users :)
@sndyuk thanks for such fantastic plugin. Since this is a follow-up question after applying the solution you've provided, I'll comment here instead.
I've noticed Tailwind class names with slash is obfuscated to a different name in HTML & CSS (example from https://tailwindcss.com/docs/translate/).
For example, this:
<div class="tw--translate-y-3/4 md:tw--translate-y-3/4">
will transform to this in HTML:
<div class="o md:o">
but this in CSS:
.sfb\/4 {..}
.md\:sfb\/4 {..}
It will be great if the bug is fixed! Looking forward to hear from you soon.
@lowjidian Thank you for the feedback!
The new version(4.0.10
) will handle the case with the configuration:
const cssObfuscatorPlugin = 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,
});