Vite 默认支持 CSS Modules,需文件名含.module.后缀且正确导入;命名错误、配置关闭、路径别名丢失后缀或Server Component中引入均会导致失效。

Vite 默认就支持 CSS Modules,只要文件名带 .module. 后缀(比如 Button.module.css),就会自动启用样式隔离——不需要装插件、也不用额外开启开关。关键是要让模块化真正生效,而不是被配置覆盖或命名写错。
确保文件命名和导入方式正确
这是最常出问题的环节。Vite 只对匹配 .module.(css|scss|less) 的文件启用模块化:
- ✅ 正确命名:
Header.module.scss、Dialog.module.css - ❌ 错误命名:
Header.scss、Dialog.css(会被当普通全局样式处理) - ✅ 导入写法:
import styles from './Header.module.scss' - ❌ 错误写法:
import './Header.module.scss'(没接收导出对象,类名不会注入)
自定义类名生成规则防冲突
默认哈希较短,多个组件里都写 .btn 仍可能偶然撞名。通过 generateScopedName 加强唯一性:
- 推荐格式:
'[name]__[local]___[hash:base64:8]'→Header__title___aBcDeFgH - 可加前缀避免项目内重名:
hashPrefix: 'myapp-' - 限制生效范围,防止误伤全局样式:
regexp: /.module\.(css|scss|less)$/i
混用局部与全局样式
一个文件里既能写模块化类,也能保留部分全局类,靠 :global() 实现:
立即学习“Java免费学习笔记(深入)”;
-
:global(.highlight) { color: red; }→ 编译后仍是.highlight -
.container :global(.btn) { padding: 8px; }→ 仅.btn逃逸,外层.container仍被模块化 - ⚠️ 注意:
:global不支持标签选择器(如:global(div)无效),也不能包裹@keyframes或CSS 变量,这些需手动加前缀或单独处理
避免常见断点
遇到 import './X.module.css' 返回空对象,大概率是以下之一:
- Vite 配置中写了
css: { modules: false },直接关掉了全部模块行为 - 用了别名(如
@/styles/X.module.css),但路径解析后丢失了.module后缀 - 在 Next.js 的
app/目录 Server Component 中 import —— 构建阶段跳过,不支持 - 全局重置样式(如
reset.css)错误地用了.module.css后缀,应去掉并只在入口main.tsx中引入一次


















