CSS Loader 默认不启用样式隔离,必须显式配置 modules: { mode: 'local' },否则无论文件名是否含 .module.css,所有类名均全局生效;Webpack 识别模块化的唯一依据是 loader 配置,而非文件名。

CSS Loader 默认不启用样式隔离,必须显式开启 modules 选项,否则所有类名都全局生效,根本谈不上隔离。
为什么 import './Button.css' 不会触发 CSS Module
Webpack 识别 CSS Module 的唯一依据是配置项,不是文件名。即使你写了 Button.module.css,但 loader 配置里没开 modules,它照样当普通 CSS 处理;反过来,哪怕叫 index.css,只要 css-loader 配了 { modules: true },它就走模块化流程。
常见错误现象:
- 样式在 DevTools 里显示为原始类名(如
.button),没被哈希化 - 多个组件的同名 class 相互覆盖,比如两个
.container冲突 - React 中用
className="button"能生效,但styles.button是undefined
正确做法是:在 webpack.config.js 的 rules 中明确传入 modules: true(或更安全的 modules: { mode: 'local' }):
立即学习“前端免费学习笔记(深入)”;
module: {
rules: [
{
test: /\.css$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
modules: { mode: 'local' }
}
}
]
}
]
}如何让 .scss 文件也支持 CSS Module 隔离
SCSS 本身不决定是否模块化,真正起作用的是 css-loader 的配置。只要 loader 链里包含启用了 modules 的 css-loader,.scss、.less、.styl 全部一视同仁。
关键点:
- 必须安装
sass和sass-loader(sass是运行时依赖,不能只装sass-loader) - loader 执行顺序必须是
style-loader → css-loader → sass-loader,因为css-loader要处理最终产出的 CSS 字符串,不是 SCSS 源码 - 文件名是否带
.module.scss是 CRA 等脚手架的约定,原生 Webpack 不管这个,只看 loader 配置
示例配置:
{
test: /\.s[ac]ss$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: { modules: { mode: 'local' } }
},
'sass-loader'
]
}modules: true 和 modules: { mode: 'local' } 有什么区别
modules: true 是旧写法,已不推荐;modules: { mode: 'local' } 是当前标准,它能避免意外将第三方 CSS(比如 node_modules 里的)也模块化。
容易踩的坑:
- 没加
mode: 'local',导致import 'normalize.css'后类名变成哈希值,样式失效 - 误以为
modules: true可以自动过滤node_modules,其实不会 - 在同一个项目中混用
modules: true和modules: { mode: 'icss' },造成部分样式无法解析@value或:export
稳妥写法是显式排除第三方:
options: {
modules: { mode: 'local' },
exclude: /node_modules/
}为什么有时 styles.xxx 是 undefined,但样式却显示出来了
这说明 CSS 被当作全局样式注入了——css-loader 没生效,或者 loader 链断了(比如漏写了 css-loader,只写了 sass-loader 和 style-loader)。
检查步骤:
- 确认
use数组里有且仅有 **一个**css-loader,并且它在sass-loader之后、style-loader之前 - 打开浏览器 DevTools → Sources → 查看打包后的 JS,搜索
__webpack_modules__里是否有该 CSS 文件对应的模块导出对象(含locals字段) - 临时把
css-loader的options.modules改成{ mode: 'icss' },如果报错说找不到@value,说明 loader 链通了;如果没报错,说明压根没走到css-loader
最隐蔽的问题:多个 rule 同时匹配同一类文件(比如一个匹配 .css,另一个匹配 .module.css),后定义的 rule 会覆盖前一个,导致模块化配置被忽略。


















