soranoo / next-css-obfuscator

A package deeply inspired by PostCSS-Obfuscator but for Next.js.
https://next-css-obfuscator.vercel.app
MIT License
71 stars 3 forks source link

Is this possible to obfuscate "hover:" class name or something like that from TailwindCSS? I also have some question and feature request #6

Closed hoangnhan2ka3 closed 7 months ago

hoangnhan2ka3 commented 7 months ago

First of all, I really appreciate your efforts on this project ✨, thank you @soranoo and all Sponsors !

This is almost what I needed, really easy to use, really full features and highly customizable. Besides, it also helps my code look mysterious 😈 and professional.

I want to make some contributions to make this project even more perfect, to be widely known and to be a perfect replacement for a certain "no longer maintained package" named Post*** πŸ˜„.

My specs:

OS: Windows 11 IDE: VS Code v1.85.2 Nextjs 14.1 Frontend cloud: Vercel Using: next-css-obfuscator v2.0.6

πŸ‘‰ 1. Also obfuscate something like "hover:" in TailwindCSS class:

There are things that are really easy to confuse like *:hover in normal CSS and hover:* in TailwindCSS class, both have hover and :.

In my test project, I have ONLY one class end with "...text-yellow-300" (I mean there is no other class named "yellow") like this:

Screenshot 2024-01-29 070831

And when npm run build, in css-obfuscator/conversion.json file:

Screenshot 2024-01-29 071613

(I also delete .next/cache folder and old css-obfuscator folder, which contain conversion.json before running this build command).

Result:

Screenshot 2024-01-29 092640

In expected:

".hover\\:text-yellow-300": ".kj33u9",

// or at least

".hover\\:text-yellow-300": ".hover\\:kj33u9",

But no. So... I don't know what is the :hover suffix (which is the main problem) when detecting that class name πŸ₯². And why it detect another alone class ".text-yellow-300" which doesn't exist.

Actually, I found a temporary solution when editing your utils.js file in the node_modules folder, I will talk about this problem in part 2.

πŸ‘‰ 2. The problem of selectorClasses.length > 1:

I think part of the problem lies in this line of utils.js: https://github.com/soranoo/next-css-obfuscator/blob/480fbb19b276b629b7eaf9df116fc4fbb65c886e/src/utils.ts#L801

When I edit it to selectorClasses.length >= 1, this is the result:

Screenshot 2024-01-29 081320

"Nears". But of course this does not work β›” too because of wrong class detected with :hover suffix.

Doesn't stop there, this edit also affects "single character" then "-[${custom parameter}]" eg: z-[9999], min-h-[80rem], etc. (almost all)

With selectorClasses.length > 1:

Screenshot 2024-01-29 092229

With selectorClasses.length >= 1:

Screenshot 2024-01-29 084939

Almost every TW custom parameter class except hover: works perfectly (for me) with selectorClasses.length >= 1. And I run dev, run build + run start or deploy to Vercel with no error (I haven't tried all the TW classes and don't know if there are any special cases or exceptions, but this works for me for now)

🫢 If possible, please update an option for this selectorClassesLength as a temporary solution for custom parameter TW class.

*πŸ‘‰ 3. Truth about select direct child [":"](https://tailwindcss.com/docs/hover-focus-and-other-states#styling-direct-children):**

If u know u know:

Screenshot 2024-01-29 094126

Even though this *: class exists in the parent div, it really only has an effect on the children div.

I'm really not sure what will happen if we successfully obfuscate this *: class ⁉️

Screenshot 2024-01-29 094937

I think it's possible but quite difficult to do hmmm...

The script is to just obfuscate the .\\*\\:font-extrabold part and I think

.jzn6lz > * {
    font-weight: 800;
}

will do the rest.

Okay and... the remain problem of *: is same same as hover:

Screenshot 2024-01-29 095924

It is true that it must be .\\*\\:font-extrabold > * to work but we don't need to detect the > * part but .\\*\\:font-extrabold right?

At last I do think that fix the hover: problem is much possible than *: haha πŸ˜„.

πŸ‘‰ 4. Feature request:

Screenshot 2024-01-29 101716

You know πŸ‘‰πŸ‘ˆ... I think this feature is not useless but it's really not as useful as doing the opposite. I mean the tag with marker class will not be obfuscated, it is more valuable to use than having to add a marker to each tag you want to obfuscate, but yes, don't delete the current option because it is usable in some cases. Is it possible?

And once again I really thank you and everyone who has contributed and built this project, please continue to develop it further πŸ₯³.

hoangnhan2ka3 commented 7 months ago

Oh, I forgot, I was very surprised that when using selectorClasses.length >= 1, the class .animate-\\[pulse-404_3s_linear_infinite\\] becomes a super concise class like .w2zhoa but still used okay haha, that's the unexpected effect of this package.

Edited: Hmmm... I am wrong. I wonder why it didn't delete the old TW class because now it's useless huh πŸ₯².

Screenshot 2024-01-29 234226

Now I know why you said in Warning "As a trade-off, the obfuscation will make your CSS files larger"

Maybe it's still not optimized as well as I thought 🀑.

soranoo commented 7 months ago

What a fantastic issue format! I really appreciate your enthusiasm and contribution to this package.

  1. Regarding the issues, I will investigate them ASAP.
  2. Regarding the opposite of obfuscate marker, I don't think it is a good idea to implement it right now. There is serious issue (see the πŸ› Known Issues) with the current obfuscate marker feature and I don't think I can solve it shortly. The bigger obstacle at this moment is the way to track functions being called within a component so that we can obstacles its children's component. I tried to parse the JS and have some proof of concepts but I don't think I have enough knowledge handling this. If you are familiar with it please, please give me some hints.
soranoo commented 7 months ago

Plus, if you have a test project for this, would you mind to share with me?

hoangnhan2ka3 commented 7 months ago

Thank you for reply!

  1. Actually, I've been intending to obfuscate this TW class for a long time. I only see facebook.com and blueagle.top available. like this, but it seems that the two still cannot agree on the number of characters in the obfuscated class, which is still not perfect (unlike your package πŸ’•).

  2. Yeah you're right, the issue of opposite markers is probably not the highest priority right now. If feasible, can you address the fixable issues first? I mean the selectorClasses.length >= 1 problem.

  3. Regarding testing project, I will comment here ASAP when I finish preparing. (Again, sorry that's as far as I can help right now). This is my test domain, you can check out. Try the 404 page with mouse wheel scroll πŸ˜„.

  4. I actually have more than one feature request πŸ˜„

If you can really do this, this will be a huge boom for your package.

waitingforamiracle

soranoo commented 7 months ago

Yes, fixing the bugs is my top priority right now.

Regarding the feature request,

  1. So you would like to replace a specific class with a class you want?
  2. Maybe I should add an option to del all TW classes if they have an obfuscated version (for full obfuscation). The reason I keep the TW classes is to prevent breaking the site when some obfuscation fails.
hoangnhan2ka3 commented 7 months ago

Yeah if you can actually delete exactly the OBFUSCATED TW classes then maybe there won't be any problem 🫑, otherwise you can try making a beta version of the package for example.

But I think you can fix the other problems first and then remove the old TW class problem for the end.

soranoo commented 7 months ago

@hoangnhan2ka3 The beta version is ready!

npm run next-css-obfuscator@beta

Looking forward to your feedback~

hoangnhan2ka3 commented 7 months ago

hi there @soranoo =))))

This my first look about the fix of *: class

Screenshot 2024-01-31 084943

Wait for me for full feedback, looks very interesting πŸ’£

soranoo commented 7 months ago

Investigation Report

  1. hover: and :hover
  2. The problem of selectorClasses.length > 1 and Tailwind universal selector

Feature Update

New README

hoangnhan2ka3 commented 7 months ago

I'm extremely honored to be tagged in the README ✨.

And I'm surprised by the structure of your code after this change quite a bit, thank you for your effective efforts πŸŽ‰.

There are actually a lot of improvements, especially with the hover: class, which is almost fine for now.

You also fixed the problem https://github.com/soranoo/next-css-obfuscator/commit/bb90dd0f259a9aa17e77d427f43fcac246a5c760#commitcomment-138032346

Screenshot 2024-01-31 115010

which is noice πŸ’•πŸ’•.

Ok now let's get to the main point.

*πŸ‘‰ 1. The Biggest One `:` class:**

hi there @soranoo =))))

This my first look about the fix of *: class

Screenshot 2024-01-31 084943

Wait for me for full feedback, looks very interesting πŸ’£

Well~, the problem is the same of hover: class I've commented on your edit https://github.com/soranoo/next-css-obfuscator/commit/bb90dd0f259a9aa17e77d427f43fcac246a5c760#commitcomment-138032286 yesterday:

Screenshot 2024-01-31 100206

Good group separation !

Screenshot 2024-01-31 100933

Screenshot 2024-01-31 102537

Yeah I mean "replace", not "change":

/* From this */
.\*\:justify-center > * {
    justify-content: center;
}

/* To this */
.\*\:hbk62l > * {
    justify-content: center;
}

IN THE CSS FILE !!!

Or at least for now, it can be called "add more". Because the problem I'm about to talk about in next part still doesn't seem to be quite right, even though you mentioned it in the Change log.

Screenshot 2024-01-31 103556

I also tried deploying to Vercel, Redeploy without caching,... but nothing changed...

πŸ‘‰ 2. Is this real πŸ€”:

In new beta Readme, you said Delete original CSS automatically after obfuscation (only apply at full obfuscation), WOW 🀯.

After reading carefully the new Tips section, I think it's an issue.

Looks like I haven't experienced that yet, don't know if it's a problem because I'm using tsx or if our version is different. As u can see, unused classes have not been deleted/ replaced. (I tried with one default and one custom TW class but same output parameter)

Screenshot 2024-01-31 105911

Easy-to-see version of View page source:

Screenshot 2024-01-31 110951

In conversion.json file:

Screenshot 2024-01-31 110821

But please don't worry, as I said before, let's solve the superficial problems first, a little file size of css file is not a big deal now, but it would be a really great option if it could be done.

I was planning to suggest more features but it doesn't seem necessary right now, I'm looking forward to your next patch @soranoo .

In addition, I also discovered some more bugs:

Screenshot 2024-01-31 111813

In my next-css-obfuscator.config.cjs:

Screenshot 2024-01-31 112404 Screenshot 2024-01-31 114415

Yeah this [pop-t], [pop-b], [pop-l] and [pop-r] is my custom attribute used for long-hover popup like this:

Screenshot 2024-01-31 113209 Screenshot 2024-01-31 113314

Just like title attribute:

Screenshot 2024-01-31 113506

The project containing pop is an old project based on static HTML so I haven't tried it on the Nextjs project this time, but I think it will also have some problem with deleting/ replacing the obfuscated class inside. css files

hoangnhan2ka3 commented 7 months ago

It seems more correct then ~ @soranoo

Before:

Screenshot 2024-01-31 110318

After:

Screenshot 2024-01-31 194007

✨ I don't see classes that should not be duplicated anymore.

But what happen with the new CSS rules count haha πŸ€”.

soranoo commented 7 months ago

Tailwind Universal Selector

classIgnore

[attribute] Selector

hoangnhan2ka3 commented 7 months ago

✨Report to commander @soranoo , mission success !

Screenshot 2024-01-31 224212 Screenshot 2024-01-31 223634 Screenshot 2024-01-31 224055

I've been trying with new CSS rules count but it still doesn't work πŸ₯² Please provide an official version to npm.

Screenshot 2024-01-31 223801
hoangnhan2ka3 commented 7 months ago

Plus, there are 2 Obfuscation in the log πŸ‘€:

Screenshot 2024-01-31 231643
soranoo commented 7 months ago

Let's have a final beta before release!

npm run next-css-obfuscator@beta

I had added/merged some options. Btw classIgnore option now supports Regex. New README

soranoo commented 7 months ago

Plus, there are 2 Obfuscation in the log πŸ‘€:

Screenshot 2024-01-31 231643

I will remove it before the official release.

hoangnhan2ka3 commented 7 months ago

Okayyyy newwww buggggg:

// layout.tsx

import localFont from 'next/font/local';

const gilroy = localFont ({
    src: [
        {
            path: "../fonts/SVN-Gilroy.woff2",
            weight: "400",
            style: "normal",
        },
        {
            path: "../fonts/SVN-GilroyMedium.woff2",
            weight: "500",
            style: "normal",
        },
        {
            path: "../fonts/SVN-GilroySemiBold.woff2",
            weight: "600",
            style: "normal",
        },
        {
            path: "../fonts/SVN-GilroyBold.woff2",
            weight: "700",
            style: "normal",
        },
        {
            path: "../fonts/SVN-GilroyHeavy.woff2",
            weight: "800",
            style: "normal",
        },
        {
            path: "../fonts/SVN-GilroyBlack.woff2",
            weight: "900",
            style: "normal",
        },
    ],
});

export default function RootLayout({
    children,
}: Readonly<{
    children: React.ReactNode;
}>) {
    return (
        <html lang="en" className={gilroy.className}>
            <head>
                <meta httpEquiv="X-UA-Compatible" content="IE=edge,chrome=1" />
                <meta name="last-modified" content={new Date().toLocaleDateString()}/>
            </head>
            <body className="dark">
                <noscript>You need to enable JavaScript to run this site.</noscript>
                <ProgressTopbar />
                <main className="flex">
                    <HomeLayout />
                    <div className="p-6 size-full">
                        {children}
                    </div>
                </main>
            </body>
        </html>
    );
}

U see <html lang="en" className={gilroy.className}>

In production, it will look like this if no obfuscation:

Screenshot 2024-01-31 233519

Please refer to Nextjs local fonts

I tried not including __className_38b0b7 in classIgnore so it looks like a normal person.

And when run this package:

In normal pages βœ…:

Screenshot 2024-01-31 234832

In 404 page β›”(a.k.a not-found.tsx page) :

Screenshot 2024-01-31 234112

Yes, fonts have not been applied.

In previous comments, I put __className_38b0b7 in classIgnore so I didn't detect this problem.

__className_38b0b7 will not change even when deploying or run build + run start or run dev, but when you add fonts or update fonts I think it will change. So I think adding exactly __className_38b0b7 to classIgnore is not a good idea, right?

soranoo commented 7 months ago

try put /__.*/ into classIgnore?

hoangnhan2ka3 commented 7 months ago

Nope,

Screenshot 2024-01-31 235339

Result 1:

Screenshot 2024-01-31 235142 Screenshot 2024-01-31 235436

Result 2:

Screenshot 2024-01-31 235304

Do you have any updates about classIgnore that I missed? Do I need to update?

I tried putting className={gilroy.className} in body as well but still the same.

hoangnhan2ka3 commented 7 months ago

okay I just updated with classIgnore which already supports Regex, everything is fine, so a class like __className_38b0b7 cannot be obfuscated, right?

I also just tried with some other Regex and they work fine too:

Screenshot 2024-02-01 002907

Result:

Screenshot 2024-02-01 003257

Thanks @soranoo πŸ’•!

soranoo commented 7 months ago

I guess yes... I will add this to the doc

hoangnhan2ka3 commented 7 months ago

So it seems like there's only one "problem" left, which is replacing the class in querySelector or something like that.

Screenshot 2024-02-01 003650

I tried removing .big and .small from classIgnore and the rotation effect no longer seems to work.

hoangnhan2ka3 commented 7 months ago

One more :)))) Sorry I'm so annoying just pointing out the bug without doing anything to help you πŸ₯².

πŸ‘‰ filter tag inside svg tag:

Screenshot 2024-02-01 005032

In the comments above, I had to put filter in classIgnore to not cause the filter tag to obfuscate, hmmm... I don't know why it detected filter tag as a class.

Screenshot 2024-02-01 005433

In conversion.json file:

Screenshot 2024-02-01 005736

OMG is it really a class 🀯? How.

Note: filter attribute was not changed βœ…:

Screenshot 2024-02-01 010832

πŸ‘‰ Also with iframe tag:

Screenshot 2024-02-01 010014 Screenshot 2024-02-01 010221

I thought it was an element of HTML huh?

Screenshot 2024-02-01 010054

With <filter>:

Screenshot 2024-02-01 010346

Without <filter>:

Screenshot 2024-02-01 010400
soranoo commented 7 months ago

So it seems like there's only one "problem" left, which is replacing the class in querySelector or something like that.

Screenshot 2024-02-01 003650

I tried removing .big and .small from classIgnore and the rotation effect no longer seems to work.

I don't think is it a good idea to use querySelector but not useRef. You are using React not jQuery

soranoo commented 7 months ago

After some testing, I decided not to edit the regex since the javascript obfuscation will messed up by that ..

hoangnhan2ka3 commented 7 months ago

That's okay, don't try too hard

soranoo commented 7 months ago

For a temp fix, add the following to the class conversion json,

{
// ....
"..big": ".big",
}
hoangnhan2ka3 commented 7 months ago

That's not called a natural deployment, right?

Okay, I'll live with .big and .small in classIgnore, no problem 🀑

soranoo commented 7 months ago

Yes, directly editing the conversion JSON is not recommended. Btw can I mention your site in the dome section?

hoangnhan2ka3 commented 7 months ago

Ok, but let me provide another domain with same content, cuz I will use hoangnhan.uk for more deployment.

U can use hoangnhan.co.uk, I will update it in a minute

hoangnhan2ka3 commented 7 months ago

hoangnhan.co.uk is ready @soranoo, I just wait for new npm package to update and u can mention it.

or when I finish my project on my main domain hoangnhanne.id.vn, you can mention it too :D.

soranoo commented 7 months ago

Please notify me when your site goes into production! Looking forward to your fantastic work.

hoangnhan2ka3 commented 7 months ago

It's just a 100dvh website haha 🀑

soranoo commented 7 months ago

@hoangnhan2ka3 The 2.1.0 is out