Хешировать имена классов nextJS v14

Как хешировать имена классов CSS для nextJS v14?

Старый способ, которым вы это делали, был примерно таким:

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");

module.exports = {
  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;
  },
};

Но в настоящее время это дает некоторые ошибки. Нравится: getLocalIdent is not found.

Вы можете напрямую использовать className = {styles.flag} внутри вашего файла JSX, но это не хэширует его с коротким кодом в производстве (например, vercel).

Поэтому я хочу, чтобы мои имена классов CSS выглядели так: 9pt5S вместо текущего navbar_flag__9pt5S (с помощью: className = {styles.flag}).

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
0
222
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Самый простой способ, аналогичный старому решению:

import loaderUtils from "loader-utils";
import path from "path";

const isProd = process.env.NODE_ENV === 'production'

const cssModuleLocalIdent = (context, _, exportName, options) => {
    const relativePath = path.relative(context.rootContext, context.resourcePath).replace(/\\+/g, "/");
    const hash = loaderUtils.getHashDigest(Buffer.from(`filePath:${relativePath}#className:${exportName}`), "sha1", "base64", 5);
    return loaderUtils.interpolateName(context, hash, options).replace(
      /\.module_/, "_")
      .replace(/[^a-zA-Z0-9-_]/g, "_")
      .replace(/^(\d|--|-\d)/, "__$1");
}

const nextConfig = {
  webpack: (config) => {
    const rules = config.module.rules
      .find((rule) => typeof rule.oneOf === 'object')
      .oneOf.filter((rule) => Array.isArray(rule.use));

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

    return config;
  },
}

export default nextConfig

Убедитесь, что у вас установлены модули loader-utils и path.

Другие вопросы по теме