你想了解在 Vite 中如何配置和使用 CSS 模块(CSS Modules),这是解决 React 项目中样式命名冲突的核心方案,Vite 对 CSS 模块提供了开箱即用的支持,同时也允许你自定义配置规则。
一、CSS 模块的基础使用(无需额外配置)
Vite 遵循 “约定大于配置” 的原则,只要将样式文件命名为 [name].module.css/[name].module.scss/[name].module.less 格式,就会自动启用 CSS 模块功能。
1. 基础使用示例(以 Scss 为例)
步骤 1:创建 CSS 模块文件(App.module.scss)
scss
// 定义样式类名(可以用驼峰/短横线命名)
.container {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}
.title {
color: #1890ff;
font-size: 24px;
font-weight: 600;
}
// 全局样式(:global 包裹,不会被模块化)
:global(.global-btn) {
padding: 8px 16px;
border: none;
border-radius: 4px;
}
步骤 2:在 React 组件中导入并使用
jsx
import React from 'react';
// 导入 CSS 模块(默认导出一个对象,包含所有类名)
import styles from './App.module.scss';
function App() {
return (
<div className={styles.container}>
{/* 使用模块化类名(自动转换为唯一名称) */}
<h1 className={styles.title}>Vite + React CSS 模块</h1>
{/* 使用全局样式(直接写类名) */}
<button className="global-btn">全局按钮</button>
</div>
);
}
export default App;
2. 关键特性说明
- 类名隔离:Vite 会将
.container编译为类似App_container_12345的唯一类名,避免不同组件样式冲突。 - :global 关键字:包裹的类名不会被模块化,可用于全局样式。
- 驼峰转换:如果类名是
app-title,可以通过styles.appTitle访问(兼容短横线命名)。
二、自定义 CSS 模块配置
如果需要修改类名生成规则、指定生效范围等,可以在 vite.config.js 中配置 css.modules 选项,以下是完整的自定义配置示例:
javascript
运行
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import path from 'path';
export default defineConfig({
plugins: [react()],
css: {
// CSS 模块核心配置
modules: {
// 1. 自定义类名生成规则(常用)
// 格式:[name](文件名)、[local](原类名)、[hash](哈希值)
generateScopedName: '[name]__[local]___[hash:base64:5]',
// 2. 指定哪些文件启用 CSS 模块(默认是 .module.*)
// 比如让所有 .scss 文件都启用模块化(无需加 .module 后缀)
// regexp: /.scss$/i,
// 3. 关闭 CSS 模块的警告(比如未使用的类名警告)
warnOnInvalidSymbols: false,
// 4. 自定义 localsConvention(类名转换规则)
localsConvention: 'camelCaseOnly', // 仅支持驼峰命名(如 appTitle)
// 可选值:
// - 'asIs':不转换(原类名)
// - 'camelCase':兼容驼峰和短横线(app-title → appTitle)
// - 'camelCaseOnly':仅驼峰
// - 'dashes':短横线(默认)
// 5. 生成 CSS 模块类型声明文件(TypeScript 项目推荐)
generateDeclarations: true,
// 6. 忽略某些文件的模块化(优先级高于 regexp)
// ignore: /global.scss$/i // 全局样式文件不启用模块化
},
// 开发环境生成 SourceMap,方便调试样式
devSourcemap: true
},
resolve: {
alias: {
'@': path.resolve(__dirname, './src')
}
}
});
三、TypeScript 项目适配
如果你的 React 项目使用 TypeScript,直接导入 .module.css/scss/less 文件可能会报 “找不到模块” 的错误,需要添加类型声明:
1. 创建类型声明文件(src/vite-env.d.ts)
typescript
运行
/// <reference types="vite/client" />
// 为 CSS 模块添加类型声明
declare module '*.module.css' {
const classes: { readonly [key: string]: string };
export default classes;
}
declare module '*.module.scss' {
const classes: { readonly [key: string]: string };
export default classes;
}
declare module '*.module.less' {
const classes: { readonly [key: string]: string };
export default classes;
}
2. 说明
- 该文件会告诉 TypeScript 识别
.module.*后缀的样式文件,并知道其导出的是一个键值对对象。 - 如果启用了
css.modules.generateDeclarations,Vite 会自动生成.d.ts文件,无需手动声明。
四、常见问题解决
-
类名访问报错「属性不存在」:
- 检查类名拼写是否一致(比如样式文件中是
appTitle,组件中写了apptitle)。 - TypeScript 项目确保添加了上述类型声明文件,或重启 TypeScript 语言服务。
- 检查类名拼写是否一致(比如样式文件中是
-
想让所有样式文件都启用模块化(无需 .module 后缀) :
-
在
css.modules.regexp中配置匹配规则,比如:javascript
运行
modules: { regexp: /.scss$/i, // 所有 .scss 文件都启用模块化 }
-
-
全局样式被模块化:
- 方法 1:使用
:global()包裹全局类名。 - 方法 2:创建不含
.module后缀的样式文件(如global.scss),直接导入即可。
- 方法 1:使用
总结
- 基础使用:样式文件命名为
[name].module.css/scss/less,导入后通过对象访问类名,自动实现样式隔离。 - 自定义配置:通过
vite.config.js的css.modules可修改类名生成规则、指定模块化文件范围、适配 TypeScript 等。 - 关键技巧:
generateScopedName控制类名格式,:global声明全局样式,TypeScript 需添加类型声明文件避免报错。