You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Vite自定义Nuxt 3中CSS Modules的哈希类名

如何生成合法的CSS Modules哈希类名(Nuxt 3 + Vite)

我在Nuxt 3项目中使用grid.module.css这类CSS Modules文件,希望自定义类名格式(比如将.grid转为.grid_grid__XyZ14),替代Vue默认的哈希格式(如.grid转为._grid_1a0w7_1)。

参考Vite的CSS Modules配置后,我尝试用Node.js的crypto模块生成哈希,但base64编码的结果偶尔会包含/和+这类CSS类名不允许的字符,导致样式无法生效。我现在用递归函数过滤这些字符,但不确定这是不是正确方案,想知道有没有更优雅的方式生成合法的哈希类名。

初始实现代码

import path from 'path'
import crypto from 'crypto'

defineNuxtConfig({
  vite: {
    css: {
      modules: {
        generateScopedName: (className, filename) => {
          const fileName = path.basename(filename, '.module.css')
          
          const hash = crypto
            .createHash('sha256')
            .update(className)
            .digest('base64')
            .substring(0, 5)

          return `${fileName}_${className}__${hash}`
        }
      }
    }
  }
})

递归过滤非法字符的实现

import path from 'path'
import crypto from 'crypto'

defineNuxtConfig({
  vite: {
    css: {
      modules: {
        generateScopedName: (className, filename) => {
          const fileName = path.basename(filename, '.module.css')

          function createHash(hash) {
            const _hash = crypto.createHash('sha256').update(hash).digest('base64').substring(0, 5)

            if (_hash.includes('/') || _hash.includes('+')) {
              return createHash(_hash)
            }

            return _hash
          }

          const hash = createHash(className)

          return `${fileName}_${className}__${hash}`
        }
      }
    }
  }
})

更优雅的解决方案

递归方案虽能解决问题,但存在重复计算哈希的额外开销,理论上还可能出现递归深度过大的情况(概率极低)。以下是几种更高效省心的替代方案:

方案1:直接替换base64中的非法字符

将base64结果里的/和+替换为CSS合法字符(如_和-),一步到位:

import path from 'path'
import crypto from 'crypto'

defineNuxtConfig({
  vite: {
    css: {
      modules: {
        generateScopedName: (className, filename) => {
          const fileName = path.basename(filename, '.module.css')
          
          const hash = crypto
            .createHash('sha256')
            .update(className)
            .digest('base64')
            .substring(0, 5)
            .replace(/\+/g, '-')
            .replace(/\//g, '_')

          return `${fileName}_${className}__${hash}`
        }
      }
    }
  }
})

方案2:使用十六进制哈希

十六进制编码的哈希仅包含0-9和a-f,完全符合CSS类名规范,无需额外处理:

import path from 'path'
import crypto from 'crypto'

defineNuxtConfig({
  vite: {
    css: {
      modules: {
        generateScopedName: (className, filename) => {
          const fileName = path.basename(filename, '.module.css')
          
          const hash = crypto
            .createHash('sha256')
            .update(className)
            .digest('hex')
            .substring(0, 5)

          return `${fileName}_${className}__${hash}`
        }
      }
    }
  }
})

方案3:利用postcss-modules内置模板

Vite的CSS Modules底层依赖postcss-modules,直接使用它的内置模板语法即可自动处理非法字符,无需手动写哈希逻辑:

defineNuxtConfig({
  vite: {
    css: {
      modules: {
        // [name]对应文件名,[local]对应原类名,[hash:base64:5]对应5位哈希(自动处理非法字符)
        generateScopedName: '[name]_[local]__[hash:base64:5]'
      }
    }
  }
})

内容的提问来源于stack exchange,提问作者dbzx10299

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 21:43:15