文件名必须严格为.module.less,webpack配置需定义lessmoduleregex并置oneof首位,css-loader须启用modules: { getlocalident: getcssmodulelocalident },且less-loader必须降级至@7.3.0兼容webpack 4。

文件名必须带 .module.less 后缀,否则 import styles from './X.module.less' 一定为空
Webpack(尤其是 CRA 或 Vite)只对匹配 /\.module\.(css|scss|sass|less|styl)$/ 的路径启用 CSS Modules 逻辑。写成 Button.less 或 Header.modules.less(拼错 module)或 index.MODULE.less(大小写不敏感但部分 loader 不识别),都会导致 styles 是空对象或原始类名字符串。
常见错误现象:console.log(styles) 输出 {} 或 {button: "button"};组件上加了 className={styles.button} 却没生效,浏览器里看到的是未哈希的原始类名,样式被全局污染。
- ✅ 正确命名:
Button.module.less、Dialog.module.less - ❌ 错误命名:
Button.less、Button.module.css(后缀不匹配)、button.Module.less(推荐全小写) - 路径大小写也要一致:Linux/macOS 下
./styles.module.less和实际文件名Styles.module.less不匹配,styles就是{}
webpack.config.js 中必须显式配置 lessModuleRegex 并置于 oneOf 规则首位
默认 Webpack 配置会先用普通 /.less$/ 规则捕获所有 Less 文件,.module.less 根本进不到 css-loader 的 modules 流程里——所以你得手动加一条专属规则,并确保它排在普通 Less 规则前面。
关键点不是“有没有配 less-loader”,而是“有没有为 .module.less 单独开一个带 modules: { getLocalIdent: getCSSModuleLocalIdent } 的规则”。
- 在
webpack.config.js顶部定义:const lessModuleRegex = /\.module\.less$/; - 在
module.rules.oneOf数组开头插入该规则,test: lessModuleRegex -
use中调用getStyleLoaders时,importLoaders: 2必须设(因为@import需要 less-loader + css-loader 共同处理) - 普通
/.less$/规则必须exclude: lessModuleRegex,且不能开modules,否则全局样式可能被 tree-shaken 掉
必须用 less-loader@7.3.0,新版会静默失败
CRA v4/v5(Webpack 4)项目中,less-loader@10+ 会报 this.getOptions is not a function,这不是配置错误,是 API 层级不兼容。loader 初始化失败 → css-loader 拿不到编译后的 CSS → styles 为空。
这个错误不会中断构建,但会导致模块化完全失效,非常隐蔽。
- 执行:
npm uninstall less-loader && npm install less-loader@7.3.0 --save-dev -
less本身可用最新版(如less@4.2.0),不影响 Ant Design 等依赖 - 若用了
customize-cra或@craco/craco,检查插件是否强制升级了less-loader版本 - 不用 eject 的项目,
craco-less默认依赖less-loader@7.x,相对安全;但自定义lessOptions字段在 v10+ 已废弃,写了也无效
className={styles.xxx} 是唯一合法写法,别拼字符串、别动态键、别用 styleName
CSS Modules 导出的是 plain object,键是原始类名,值是哈希后字符串(如 Button_button__axY7)。它不支持运行时计算键名,也不兼容旧版 react-css-modules 的 styleName 写法。
TS 会直接报错,JS 运行时可能取到 undefined,最终渲染成 className="undefined"。
- ✅ 正确:
className={styles.button}、className={clsx(styles.button, props.primary && styles.primary)} - ❌ 错误:
className="button"(退化为全局)、className={styles['btn-' + type]}(TS 报错,运行时 undefined) - ❌ 错误:
styleName="button"(react-css-modules语法,CRA 不认,且已废弃) - 伪类和嵌套必须写在同一选择器下:
.button:hover可以,.container .item不行(两个类被分别哈希,无法匹配)
styles 就是空的,还查不出原因。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











