CSS Modules в Vite обеспечивают изоляцию стилей на уровне компонентов
за счёт автоматической генерации уникальных классов. Механизм встроен в
сборщик и не требует подключения дополнительных плагинов. Конфигурация
осуществляется через поле css.modules в
vite.config.js или vite.config.ts.
При импорте CSS-файла с суффиксом .module.css Vite
автоматически включает модульный режим:
/* button.module.css */
.button {
padding: 10px 16px;
background: black;
color: white;
}
import styles from './button.module.css'
export function Button() {
const el = document.createElement('button')
el.className = styles.button
el.textContent = 'Click'
return el
}
На этапе сборки класс .button преобразуется в уникальный
идентификатор, например:
button_button__3x9aK
css.modules в ViteОсновные параметры находятся в объекте css.modules:
// vite.config.ts
import { defineConfig } from 'vite'
export default defineConfig({
css: {
modules: {
scopeBehaviour: 'local'
}
}
})
scopeBehaviourОпределяет поведение по умолчанию для CSS Modules.
local — все классы считаются модульными по
умолчаниюglobal — классы считаются глобальными, пока не указано
иноеcss: {
modules: {
scopeBehaviour: 'local'
}
}
При global поведение можно переопределять через
:local и :global:
:local(.button) {
color: red;
}
:global(.reset) {
margin: 0;
}
generateScopedNameКонтролирует формат генерации уникальных имён классов.
css: {
modules: {
generateScopedName: '[name]__[local]___[hash:base64:5]'
}
}
Доступные токены:
[name] — имя файла[local] — исходный класс[hash] — хеш содержимого[hash:base64:5] — укороченный вариант хешаПример результата:
button__wrapper___aB3xZ
Позволяет полностью контролировать формат:
css: {
modules: {
generateScopedName: (name, filename, css) => {
return `${name}_${Math.random().toString(36).slice(2, 6)}`
}
}
}
Функция получает:
name — локальное имя классаfilename — путь к файлуcss — содержимое CSSlocalsConventionОпределяет стиль экспорта имён классов в JavaScript.
css: {
modules: {
localsConvention: 'camelCase'
}
}
camelCase — преобразование my-class →
myClasscamelCaseOnly — доступ только в camelCase формеdashes — сохранение дефисовdashesOnly — только дефисная формаlocalsConvention.card-item {
padding: 10px;
}
import styles from './card.module.css'
styles.cardItem
styles['card-item']
hashPrefixДобавляет дополнительный префикс в хеширование классов. Используется для предотвращения коллизий при одинаковых именах классов в разных проектах или частях системы.
css: {
modules: {
hashPrefix: 'projectA'
}
}
Даже при одинаковом CSS результат хеша будет отличаться.
globalModulePathsПозволяет задать файлы, которые будут обрабатываться как глобальные
CSS, даже если они имеют расширение .module.css.
import path from 'path'
css: {
modules: {
globalModulePaths: [
path.resolve(__dirname, 'src/styles/global.module.css')
]
}
}
Vite не генерирует типы для CSS Modules автоматически, но поддержка включается через декларации:
declare module '*.module.css' {
const classes: { [key: string]: string }
export default classes
}
Для более строгой типизации часто используется генерация
.d.ts файлов:
declare const styles: {
readonly button: string
readonly container: string
}
export default styles
import styles from './layout.module.css'
document.body.className = styles.layout
import styles from './layout.module.css'
const className: string = styles.layout
<template>
<div :class="$style.container"></div>
</template>
<style module>
.container {
padding: 20px;
}
</style>
CSS Modules в Vite поддерживают совместное использование локальных и глобальных правил:
:global(body) {
margin: 0;
}
.wrapper {
padding: 10px;
}
import a from './a.module.css'
import b from './b.module.css'
Каждый модуль получает собственное пространство имён. Даже одинаковые классы:
.button
будут преобразованы в разные финальные имена в зависимости от файла-источника.
import styles from './card.module.css'
element.className = `${styles.card} ${styles.active}`
Для более сложных сценариев используется clsx или
аналог:
import clsx from 'clsx'
import styles from './card.module.css'
element.className = clsx(styles.card, {
[styles.active]: isActive
})
CSS Modules в Vite обрабатываются через esbuild и PostCSS pipeline, что обеспечивает:
CSS Modules не конфликтуют с PostCSS-плагинами:
css: {
postcss: {
plugins: [
require('autoprefixer')
]
},
modules: {
generateScopedName: '[hash:base64:6]'
}
}
В production-режиме:
.module.css:global<style> без поддержки фреймворка