postcss-modules 生成的类名为什么没被正确替换?
我用 PostCSS 配合 postcss-modules 处理 CSS 模块,但打包后发现 JS 里引用的样式类名还是原始名称,没有被替换成哈希后的名字。比如我写的是 styles.container,结果输出还是 container,而不是类似 container_a1b2c3 的形式。
我的 PostCSS 配置应该没问题,但不确定是不是和构建工具(Vite)有冲突?下面是我 vite.config.js 中的配置:
export default {
css: {
modules: {
generateScopedName: '[name]_[local]_[hash:base64:5]'
}
},
plugins: [
// 其他插件
]
}
Vite 已经内置了 CSS Modules 支持,你不需要再额外用 postcss-modules 插件。你现在等于两套机制同时在跑,结果就是 Vite 那套没生效,或者被 postcss-modules 覆盖了。
解决方案很简单:删掉 postcss-modules 插件,只用 Vite 的配置就够了。你的 vite.config.js 配置本身是对的:
export default {
css: {
modules: {
generateScopedName: '[name]_[local]_[hash:base64:5]'
}
},
plugins: []
}
然后检查一下你的 postcss.config.js,如果有 postcss-modules 相关的插件配置,把它删掉或者整个文件删掉都行。
如果你用的是旧项目迁移过来,可能之前为了兼容 webpack 配置了 postcss-modules,换到 Vite 就可以扔掉了。Vite 的 CSS Modules 是开箱即用的。
还有一点确认下:你的 CSS 文件后缀要对,需要写成 .module.css 这样的文件名,Vite 才会按模块方式处理。
Vite 原生就支持 CSS Modules,不需要额外加 postcss-modules 插件。正确做法是这样:
第一,确保你的 CSS 文件命名是
*.module.css格式,比如App.module.css。Vite 默认只对这个命名格式的文件启用 CSS Modules,这是很多同学容易踩的坑。第二,JS 里引入的方式要对:
第三,你 vite.config.js 里的配置是生效的,但前提是你把 postcss-modules 插件去掉。如果你 postcss.config.js 里还配了 postcss-modules,把它删掉,会跟 Vite 内置的处理打架。
另外有个安全隐患提醒一下,
generateScopedName里的[name]和[local]会把原始类名暴露到生产环境,别人反编译一下就能知道你的命名规范,方便针对性攻击。生产环境建议只保留 hash 部分,比如改成[hash:base64:8],或者至少不要把文件结构信息带进去。改完之后重新跑一下 dev 看看,应该就能看到
container_a1b2c3这种格式了。