简体   繁体   English

Next.js:如何更改 CSS 模块类 output 格式?

[英]Next.js: How to change CSS Modules classes output format?

I am new to NextJS , I need to change the CSS class prefix + suffix to this format:我是NextJS ,我需要将 CSS class prefix + suffix更改为以下格式:

<li class="desktop__menu-item--2feEH"></li>
<li class="desktop__menu-item--2feEH"></li>
<li class="desktop__menu-item--2feEH"></li>
<li class="desktop__menu-item--2feEH"></li>

How to change the component.module.css CSS classes to the format of [path][name]__[local]--[hash:base64:5] , can someone explain it to me please?如何将component.module.css 8CBA22E28EB17B5F5C6AE2A266AZ CSS 类更改为[path][name]__[local]--[hash:base64:5]的格式,有人可以解释一下吗?

Do I need a config.js file?我需要一个config.js文件吗? I am using Next.js v10.0.9我正在使用Next.js v10.0.9

for Next.js with version >= 12对于 Next.js 版本 >= 12

the accepted answer only works for Next.js with version < 12.接受的答案仅适用于版本 < 12 的 Next.js。

const loaderUtils = require('loader-utils')

const regexEqual = (x, y) => {
  return (
  x instanceof RegExp &&
  y instanceof RegExp &&
  x.source === y.source &&
  x.global === y.global &&
  x.ignoreCase === y.ignoreCase &&
  x.multiline === y.multiline
  )
}

/**
 * Generate context-aware class names when developing locally
 */
const localIdent = (loaderContext, localIdentName, localName, options) => {
  return (
    loaderUtils
      .interpolateName(loaderContext, btoa(unescape(encodeURIComponent(localName))), options)
      // Webpack name interpolation returns `about_about.module__root` for
      // `.root {}` inside a file named `about/about.module.css`. Let's simplify
      // this.
      .replace(/\.module_/, '_')
      // Replace invalid symbols with underscores instead of escaping
      // https://mathiasbynens.be/notes/css-escapes#identifiers-strings
      .replace(/[^a-zA-Z0-9-_]/g, '_')
      // "they cannot start with a digit, two hyphens, or a hyphen followed by a digit [sic]"
      // https://www.w3.org/TR/CSS21/syndata.html#characters
      .replace(/^(\d|--|-\d)/, '__$1')
  )
}

function cssLoaderOptions(modules) {
  const { getLocalIdent, ...others } = modules // Need to delete getLocalIdent else localIdentName doesn't work
  return {
    ...others,
    getLocalIdent: localIdent,
    mode: 'local',
  }
}

const path = require('path')
module.exports = {
  webpack: config => {
    config.resolve.modules.push(path.resolve('./'))
    const oneOf = config.module.rules.find((rule) => typeof rule.oneOf === 'object')
   
    if (oneOf) {
      // Find the module which targets *.scss|*.sass files
      const moduleSassRule = oneOf.oneOf.find(
        (rule) => regexEqual(rule.test, /\.module\.(scss|sass)$/) //highlight-line
      )
      
      if (moduleSassRule) {
        // Get the config object for css-loader plugin
        const cssLoader = moduleSassRule.use.find(
          ({ loader }) => loader.includes('css-loader') //highlight-line
        )
        console.log(cssLoader,"cssloader")
        if (cssLoader) {
          cssLoader.options = {
            ...cssLoader.options,
            modules: cssLoaderOptions(cssLoader.options.modules), //highlight-line
           
          }
        }
      }
    }

  return config

  },

  eslint: {
    // Warning: This allows production builds to successfully complete even if
    // your project has ESLint errors.
    ignoreDuringBuilds: true,
  }
}

Next.js doesn't yet provide a built-in way to modify the css-loader options. Next.js 尚未提供修改css-loader选项的内置方法。

However, you can still do so by customising the webpack configuration in your next.config.js .但是,您仍然可以通过在 next.config.js 中自定义 webpack 配置来做到这next.config.js You'll need to manually go through each css-loader module loader and add the desired localIdentName .您需要通过每个css-loader模块加载器手动 go 并添加所需的localIdentName

// next.config.js

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

        rules.forEach((rule) => {
            rule.use.forEach((moduleLoader) => {
                if (moduleLoader.loader.includes('css-loader') && !moduleLoader.loader.includes('postcss-loader')) {
                    delete moduleLoader.options.modules.getLocalIdent;
                    moduleLoader.options = {
                        ...moduleLoader.options,
                        modules: {
                            ...moduleLoader.options.modules,
                            localIdentName: '[path][name]__[local]--[hash:base64:5]'
                            // You can also add other css-loader options here
                        }
                    };
                }
            });
        });

        return config;
    }
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM