Skip to content

A package deeply inspired by PostCSS-Obfuscator but for Next.js.

License

Notifications You must be signed in to change notification settings

soranoo/next-css-obfuscator

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

23 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

NEXT-CSS-OBFUSCATOR

Project start on 30-10-2023

Tests MIT LicenseΒ Β Β Donation

npm version npm downloads

πŸŽ‰ Version 2 has NOW been released πŸŽ‰

This version is deeply inspired by PostCSS-Obfuscator. Shout out to n4j1Br4ch1D for creating such a great package and thank you tremor for sponsoring this project.

Changes:

  • Support basic partially obfuscation
  • Support TailwindCSS Dark Mode
  • New configuration file next-css-obfuscator.config.cjs
  • More configuration options
  • Now become a independent sulotion (no need to patch PostCSS-Obfuscator anymore)
  • More tests
  • Better CSS parsing

Migration Guide:

version 1.x README

Give me a ⭐ if you like it.

πŸ“– Table of Contents

πŸ€” Why this?

Because in the current version of PostCSS-Obfuscator does not work with Next.js. (see this issue for more details)

πŸ’‘ How does it work?

Where is issue in PostCSS-Obfuscator?

PostCSS-Obfuscator will not edit the build files instead it will create a new folder and put the obfuscated source code files in it. This is where the issue is. Next.js will not recognize the obfuscated files and will not include them in the build. I tried to point Nextjs to build the obfuscated files (by simply change the obfuscated source code folder to src) but it didn't work.

How does this package solve the issue?

Edit the build files directly. (It may not be the best solution but it works.)

How does this package work?

  1. Extract and parse CSS files from the build files.
  2. Obfuscate the CSS selectors and save to a JSON file.
  3. Search and replace the related class names in the build files with the obfuscated class names.

πŸ—οΈ Features

  • WORK WITH NEXT.JS !!!!!!!!!!!!!!!!!!!

Note

This package is NOT guaranteed to work with EVERYONE. Check the site carefully before using it in production.

Warning

As a trade-off, the obfuscation will make your CSS files larger.

πŸ› οΈ Development Environment

Environment Version
OS Windows 11 & Ubuntu 22.04
Node.js v.18.17.1
NPM v.10.1.0
Next.js (Page Router) v.13.5.4 & v.13.4.1
Next.js (App Router) v.14.0.4
TailwindCSS v.3.3.3
  • βœ… Tested and works with Next.js Page Router and App Router.
  • βœ… Tested and works with Vercel.

(Theoretically it supports all CSS frameworks but I only tested it with TailwindCSS.)

πŸš€ Getting Started

Installation

npm install -D  next-css-obfuscator

Visit the npm page.

Setup

  1. Create and add the following code to next-css-obfuscator.config.cjs or next-css-obfuscator.config.ts:

    Obfuscate all files
    module.exports = {
        enable: true,
        mode: "random", // random | simplify
        refreshClassConversionJson: false, // recommended set to true if not in production
        allowExtensions: [".jsx", ".tsx", ".js", ".ts", ".html", ".rsc"],
      };
    Partially obfuscate
    module.exports = {
        enable: true,
        mode: "random", // random | simplify
        refreshClassConversionJson: false, // recommended set to true if not in production
        allowExtensions: [".jsx", ".tsx", ".js", ".ts", ".html", ".rsc"],
    
        enableMarkers: true,
      };
    TypeScript
    import { Options } from "next-css-obfuscator";
    
    module.exports = {
      // other options ...
    } as Options;

    Feel free to checkout πŸ“– PostCSS Options Reference for more options and details.

    [!NOTE]
    The obfuscation will never work as expected, tweak the options with your own needs.

  2. Add the following code to package.json:

    "scripts": {
     // other scripts ...
     "obfuscate-build": "next-css-obfuscator"
     },

    Read πŸ’» CLI for more details.

Usage πŸŽ‰

  1. Run npm run build to build the project.
  2. Run npm run obfuscate-build to obfuscate the css files.

(You may need to delete the .next/cache folder before running npm run start to make sure the obfuscation takes effect. And don't forget to shift + F5 refresh the page.`)

Warning

NEVER run obfuscate-build twice in a row. It may mess up the build files and obfuscation convertion table. You can remove the classConversionJsonFolderPath(default: css-obfuscator) folder to reset the convertion table.

Note

For better development experience, it is recommanded to enable refreshClassConversionJson option in next-css-obfuscator.config.cjs and disable it in production.

For convenience, you may update your build script to:

// package.json

"scripts": {
  // other scripts ...
  "build": "next build && npm run obfuscate-build"
},

to make sure the build is always obfuscated and no need to run obfuscate-build manually.

Partially obfuscate

To partially obfuscate your project, you have to add the obfuscate marker class to the components you want to obfuscate.

// example

export default function HomePage() {
  return (
    <main className="flex min-h-screen flex-col items-center justify-center bg-gradient-to-b from-[#fac3e3] to-[#5c9cbd] text-white">
      <div className="container flex flex-col items-center justify-center gap-12 px-4 py-16 ">
        <h1 className="text-5xl font-extrabold tracking-tight text-white sm:text-[5rem]">
          Next14 App Router
        </h1>
      </div>
-     <div className="container flex flex-col items-center justify-center gap-12 px-4 py-16 ">
+     <div className="next-css-obfuscation container flex flex-col items-center justify-center gap-12 px-4 py-16 ">
        <span className="text-2xl font-extrabold tracking-tight text-gray-700 border-2 border-blue-950 rounded-lg p-4">
          My classes are obfuscated
        </span>
      </div>
    </main>
  );
}

See Next 14 App Router Partially Obfuscated Demo for more details.

πŸ”§ My Setting

If you are interested in my setting (from my production site), here it is

// next-css-obfuscator.config.cjs

module.exports = {
  enable: true,
  mode: "random", // random | simplify
  refreshClassConversionJson: false, // recommended set to true if not in production
  allowExtensions: [".jsx", ".tsx", ".js", ".ts", ".html", ".rsc"],

  blackListedFolderPaths: ["./.next/cache"],
  excludeAnyMatchRegexes: [
    /\.next\/server\/pages\/api/,
    /_document..*js/,
    /_app-.*/,
  ],
  customTailwindDarkModeSelector: "dm",
};

It may not be the best setting but it works for me. :)

πŸ“– PostCSS Options Reference

Option Type Default Description
enable boolean true Enable or disable the obfuscation.
mode string "random" Obfuscate mode, "random" or "simplify".
buildFolderPath string "./.next" The folder path to store the build files built by Next.js.
classConversionJsonFolderPath string "./css-obfuscator" The folder path to store the before obfuscate and after obfuscated classes conversion table.
refreshClassConversionJson boolean false Refresh the class conversion JSON file(s) at every obfuscation. Good for setting tweaking but not recommended for production.
classLength number 5 The length of the obfuscated class name if in random mode.
classPrefix string "" The prefix of the obfuscated class name.
classSuffix string "" The suffix of the obfuscated class name.
classIgnore string[ ] [ ] The class names to be ignored during obfuscation.
allowExtensions string[ ] [".jsx", ".tsx", ".js", ".ts", ".html", ".rsc"] The file extensions to be processed.
contentIgnoreRegexes RegExp[ ] [ ] The regexes to match the content to be ignored during obfuscation.
whiteListedFolderPaths string[ ] [ ] The folder paths to be processed. Empty array means all folders will be processed.
blackListedFolderPaths string[ ] [ ] The folder paths to be ignored.
includeAnyMatchRegexes RegExp[ ] [ ] The regexes to match the file/folder paths to be processed.
excludeAnyMatchRegex RegExp[ ] [ ] The regexes to match the file/folder paths to be ignored.
enableMarkers boolean false Enable or disable the obfuscation markers.
markers string[ ] [ ] Classes that indicate component(s) need to obfuscate.
removeMarkersAfterObfuscated boolean true Remove the obfuscation markers from HTML elements after obfuscation.
customTailwindDarkModeSelector string | null null [TailwindCSS ONLY] The custom new dark mode selector, e.g. "dark-mode".
logLevel "debug" | "info" | "warn" | "error" | "success" "info" The log level.
All options in one place
module.exports = {
    enable: true, // Enable or disable the plugin.
    mode: "random", // Obfuscate mode, "random" or "simplify".
    buildFolderPath: ".next", // Build folder of your project.
    classConversionJsonFolderPath: "./css-obfuscator", // The folder path to store the before obfuscate and after obfuscated classes conversion table.
    refreshClassConversionJson: false, // Refresh the class conversion JSON file.

    classLength: 5, // Length of the obfuscated class name.
    classPrefix: "", // Prefix of the obfuscated class name.
    classSuffix: "", // Suffix of the obfuscated class name.
    classIgnore: [], // The class names to be ignored during obfuscation.
    allowExtensions: [".jsx", ".tsx", ".js", ".ts", ".html", ".rsc"], // The file extensions to be processed.
    contentIgnoreRegexes: [], // The regexes to match the file content to be ignored during obfuscation.

    whiteListedFolderPaths: [], // Only obfuscate files in these folders
    blackListedFolderPaths: ["./.next/cache"], // Don't obfuscate files in these folders
    includeAnyMatchRegexes: [], // The regexes to match the file/folder paths to be processed.
    excludeAnyMatchRegexes: [], // The regexes to match the file/folder paths to be ignored.
    enableMarkers: false, // Enable or disable the obfuscate marker classes.
    markers: ["next-css-obfuscation"], // Classes that indicate component(s) need to obfuscate.
    removeMarkersAfterObfuscated: true, // Remove the obfuscation markers from HTML elements after obfuscation.
    customTailwindDarkModeSelector: null, // [TailwindCSS ONLY] The custom new dark mode selector, e.g. "dark-mode".

    logLevel: "info", // Log level
};

πŸ’» CLI

next-css-obfuscator --config ./path/to/your/config/file

πŸ’‘ Tips

1. Not work at Vercel after updated ?

If you are using this package with Vercel, you may found the package not work as expected after updated. This is because Vercel will cache the last build for a faster build time. To fix this you have to redeploy with the Use existing build cache option disabled.

2. Lazy Setup - Obfuscate all files

Enable enableMarkers and put the obfuscate marker class at every component included the index page. But if you want to set and forget, you must play with the options to ensure the obfuscation works as expected.

3. It was working normally just now, but not now?

Your convertion table may be messed up. Try to delete the classConversionJsonFolderPath(default: css-obfuscator) folder to reset the convertion table.

πŸ‘€ Demos

  1. Next 14 App Router
  2. Next 14 App Router Partially Obfuscated

⭐ TODO

  • Partially obfuscation
  • To be a totally independent package (remove dependency on PostCSS-Obfuscator)
  • More tests

πŸ› Known Issues

  • Partially obfuscation
    • Not work with complex component. (eg. A component with children components)
      • Reason: The obfuscation marker can't locate the correct code block to obfuscate.

πŸ’– Sponsors

Organizations (1)


tremor

Individuals (0)

🀝 Contributing

Contributions are welcome! If you find a bug or have a feature request, please open an issue. If you want to contribute code, please fork the repository and run npm run test before submit a pull request.

πŸ“ License

This project is licensed under the MIT License - see the LICENSE file for details

β˜• Donation

Love it? Consider a donation to support my work.

"Donation" <- click me~