CSS Modules 是原生 HTML 项目中实现真正作用域隔离的最稳妥方案,其核心是构建工具自动重命名 class(如 .button → _button_1x2y3),避免全局污染,需配合 Webpack/Vite 等构建工具使用,纯 HTML 无效。
CSS Modules 是目前原生 HTML 项目中实现真正作用域隔离的最稳妥方案,不是“可选”,而是“该用就用”——尤其当你在多个页面复用同一类名(比如 .btn)又不想加前缀、也不愿引入构建工具全家桶时。
CSS Modules 的核心不是靠人写对名字,而是让构建工具自动重命名 class。你写 .button,它编译后变成类似 _button_1x2y3 这样的唯一标识,天然避免全局污染。
header__nav--active 这类长名,写法轻量:global() 按需穿透,比纯 CSS-in-JS 更贴近传统工作流.css 文件无效关键不是加一堆 loader,而是确保 css-loader 的 modules 开关打开,并且路径匹配正确。
node_modules 和公共样式(如 common.css),否则第三方库样式会崩modules: true 是基础,但建议显式加 localIdentName 控制生成名,例如 [name]_[local]_[hash:6],便于调试css-loader 必须放在 sass-loader / less-loader 之后,顺序错了 class 就不会被处理MiniCssExtractPlugin.loader(生产环境)或 style-loader(开发环境),否则样式不生效不能直接在 HTML 里写 class="button" —— 那个名字在运行时已经不存在了。必须通过 JS 加载模块,再把真实 class 注入 DOM。
立即学习“前端免费学习笔记(深入)”;
.jsx 或 .tsx 中:import styles from './Button.module.css';,然后 className={styles.button}
import('./Button.module.css').then(css => { ... }) 动态加载,再用 document.body.classList.add(Object.values(css)[0])(不推荐,破坏语义)import './Button.module.css'(没解构)→ class 名丢失;或误以为 require 返回字符串 → 实际返回的是对象css-loader + style-loader + locals 模式,再配合 getLocalIdent 自定义逻辑,但复杂度陡增模块化不是万能胶,几个硬伤得提前知道:
@import 在 .module.css 中默认不触发模块化 —— 被 import 的文件仍按全局处理,除非它自己也是 .module.css
@keyframes)名不会被哈希,必须手动加 :global() 包裹,否则动画找不到目标exportLocalsConvention
真正卡住人的从来不是“怎么配”,而是没想清楚:这个模块到底该暴露哪些 class 给外部?要不要留 :global(.reset)?动画要不要抽成独立文件?这些设计决策比 loader 配置重要得多。