在 Vite 中配置 CSS 模块

你想了解在 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

css 复制代码
// 定义样式类名(可以用驼峰/短横线命名)
.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

javascript 复制代码
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

运行

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

运行

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 文件,无需手动声明。

四、常见问题解决

  1. 类名访问报错「属性不存在」

    • 检查类名拼写是否一致(比如样式文件中是 appTitle,组件中写了 apptitle)。
    • TypeScript 项目确保添加了上述类型声明文件,或重启 TypeScript 语言服务。
  2. 想让所有样式文件都启用模块化(无需 .module 后缀)

    • css.modules.regexp 中配置匹配规则,比如:

      javascript

      运行

      javascript 复制代码
      modules: {
        regexp: /.scss$/i, // 所有 .scss 文件都启用模块化
      }
  3. 全局样式被模块化

    • 方法 1:使用 :global() 包裹全局类名。
    • 方法 2:创建不含 .module 后缀的样式文件(如 global.scss),直接导入即可。

总结

  1. 基础使用 :样式文件命名为 [name].module.css/scss/less,导入后通过对象访问类名,自动实现样式隔离。
  2. 自定义配置 :通过 vite.config.jscss.modules 可修改类名生成规则、指定模块化文件范围、适配 TypeScript 等。
  3. 关键技巧generateScopedName 控制类名格式,:global 声明全局样式,TypeScript 需添加类型声明文件避免报错。
相关推荐
Ne0_bbk2 小时前
# ComfyUI+OpenClaw协同工作——七个坑,记录
github
wAIxiSeu2 小时前
开源项目分享——CLI-Anything
开源·github
研究点啥好呢4 小时前
3月19日GitHub热门项目推荐|OpenClaw棋逢对手
人工智能·ai·开源·github
猫头虎4 小时前
从零开始,一步步安装和配置OpenClaw汉化版详细安装指南
langchain·开源·prompt·github·aigc·ai编程·agi
wuyaolong0075 小时前
Git误操作急救手册大纲
ui·github
MicrosoftReactor5 小时前
技术速递|面向无障碍的持续 AI:GitHub 如何将反馈转化为包容性
人工智能·github
青晚舟19 小时前
AI 时代前端还要学 Docker & K8s 吗?我用一次真实部署经历说清楚
前端·github
星浩AI19 小时前
现在最需要被 PUA 的,其实是 AI
人工智能·后端·github
AI程序员20 小时前
Pi Monorepo 学习指南
github