Home > OS >  How to hash CSS module class names in Nextjs 13?
How to hash CSS module class names in Nextjs 13?

Time:12-05

How can I edit/minify/hash/hide/obfuscate css class names in Next JS?

I tried many ways including this thread

Getting the following errors when trying this solution.

yarn build
yarn run v1.22.19
$ next build
warn  - You have enabled experimental feature (appDir) in next.config.js.
warn  - Experimental features are not covered by semver, and may cause unexpected or broken application behavior. Use at your own risk.
info  - Thank you for testing `appDir` please leave your feedback at https://nextjs.link/app-feedback

warn  - The @next/font/google font Inter has no selected subsets. Please specify subsets in the function call or in your next.config.js, otherwise no fonts will be preloaded. Read more: https://nextjs.org/docs/messages/google-fonts-missing-subsets
info  - Creating an optimized production build
Failed to compile.

HookWebpackError: Unexpected '/'. Escaping special characters with \ may help.
    at makeWebpackError (C:\k\vercel\node_modules\.pnpm\[email protected]_m5sxuueb27gk6ddc5gums6vtgq\node_modules\next\dist\compiled\webpack\bundle5.js:28:308185)   
    at C:\k\vercel\node_modules\.pnpm\[email protected]_m5sxuueb27gk6ddc5gums6vtgq\node_modules\next\dist\compiled\webpack\bundle5.js:28:105236
    at eval (eval at create (C:\k\vercel\node_modules\.pnpm\[email protected]_m5sxuueb27gk6ddc5gums6vtgq\node_modules\next\dist\compiled\webpack\bundle5.js:13:28771), <anonymous>:44:1)
-- inner error --
Error: Unexpected '/'. Escaping special characters with \ may help.
    at C:\k\vercel\static\css\9db6a345a2f242fe.css:1:817
    at Root._error (C:\k\vercel\node_modules\.pnpm\[email protected]_m5sxuueb27gk6ddc5gums6vtgq\node_modules\next\dist\compiled\cssnano-simple\index.js:190:78465)   
    at Root.error (C:\k\vercel\node_modules\.pnpm\[email protected]_m5sxuueb27gk6ddc5gums6vtgq\node_modules\next\dist\compiled\cssnano-simple\index.js:190:124360)   
    at Parser.error (C:\k\vercel\node_modules\.pnpm\[email protected]_m5sxuueb27gk6ddc5gums6vtgq\node_modules\next\dist\compiled\cssnano-simple\index.js:190:86811)  
    at Parser.unexpected (C:\k\vercel\node_modules\.pnpm\[email protected]_m5sxuueb27gk6ddc5gums6vtgq\node_modules\next\dist\compiled\cssnano-simple\index.js:190:87297)
    at Parser.combinator (C:\k\vercel\node_modules\.pnpm\[email protected]_m5sxuueb27gk6ddc5gums6vtgq\node_modules\next\dist\compiled\cssnano-simple\index.js:190:85544)
    at new Parser (C:\k\vercel\node_modules\.pnpm\[email protected]_m5sxuueb27gk6ddc5gums6vtgq\node_modules\next\dist\compiled\cssnano-simple\index.js:190:78322)    
    at Processor._root (C:\k\vercel\node_modules\.pnpm\[email protected]_m5sxuueb27gk6ddc5gums6vtgq\node_modules\next\dist\compiled\cssnano-simple\index.js:190:95242)
    at Processor._runSync (C:\k\vercel\node_modules\.pnpm\[email protected]_m5sxuueb27gk6ddc5gums6vtgq\node_modules\next\dist\compiled\cssnano-simple\index.js:190:95749)


> Build failed because of webpack errors
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

CodePudding user response:

Thanks to @brc-dd for updating his answer here.

The following config worked for me.

const path = require("path");
const loaderUtils = require("loader-utils");

const hashOnlyIdent = (context, _, exportName) =>
  loaderUtils
    .getHashDigest(
      Buffer.from(
        `filePath:${path
          .relative(context.rootContext, context.resourcePath)
          .replace(/\\ /g, "/")}#className:${exportName}`
      ),
      "md4",
      "base64",
      6
    )
    .replace(/[^a-zA-Z0-9-_]/g, "_")
    .replace(/^(-?\d|--)/, "_$1");

/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: true,
  experimental: {
    appDir: true,
  },

  webpack(config, { dev }) {
    const rules = config.module.rules
      .find((rule) => typeof rule.oneOf === "object")
      .oneOf.filter((rule) => Array.isArray(rule.use));

    if (!dev)
      rules.forEach((rule) => {
        rule.use.forEach((moduleLoader) => {
          if (
            moduleLoader.loader?.includes("css-loader") &&
            !moduleLoader.loader?.includes("postcss-loader")
          )
            moduleLoader.options.modules.getLocalIdent = hashOnlyIdent;
        });
      });

    return config;
  },
};

module.exports = nextConfig;

CodePudding user response:

To hash CSS module class names in Nextjs 13, you can use the getLocalIdent function from the css-loader package. To configure the css-loader to hash CSS module class names, follow these steps:

Install the css-loader package by running npm install css-loader or yarn add css-loader in your project's root directory.

In your next.config.js file, add the following code to configure the css-loader to hash CSS module class names:

const { getLocalIdent } = require('css-loader');

module.exports = {
  webpack: (config) => {
    config.module.rules.push({
      test: /\.css$/,
      use: [
        {
          loader: 'css-loader',
          options: {
            modules: {
              getLocalIdent: (context, localIdentName, localName, options) => {
                // Generate a hashed class name using the `getLocalIdent` function
                return getLocalIdent(context, localIdentName, localName, {
                  ...options,
                  // Enable hashing of class names
                  hashPrefix: 'hash',
                });
              },
            },
          },
        },
      ],
    });

    return config;
  },
};

In your CSS module files, import the css-loader package and use the locals property to access the hashed class names:

@import 'css-loader/locals';

.class-name {
  /* CSS styles */
}

In your React components, use the className prop to apply the hashed class names to your elements:

import styles from './styles.css';

const MyComponent = () => (
  <div className={styles.className}>
    {/* Content */}
  </div>
);

With this setup, the css-loader will automatically hash the class names in your CSS modules and make them unique for each component. This can help prevent conflicts and ensure that your styles are applied correctly.

this an Ai generated answer

  • Related