<p>@warn 仅在 SCSS 编译阶段对被引用的 @function/@mixin 生效,无法拦截 HTML 中 class;需封装为 legacy- 前缀函数并配合 PostCSS 插件扫描模板文件,且须配置构建工具启用警告输出。</p>

@warn 不能拦截 HTML 中的 class,只作用于 SCSS 编译过程
@warn 不是运行时检查工具,它只在 Sass 编译阶段执行一次,且仅对 @mixin、@function 或变量引用生效。你在 SCSS 文件里写 @warn "btn-large 已废弃",只有当这行代码被实际解析(比如有人 @include button-large())才会触发;如果团队直接在 HTML 里写 class="btn-large",或在 Vue 模板中硬编码,@warn 完全无感。
常见误判是以为加了 @warn 就等于“禁用成功”。实际上它不阻止任何输出,也不扫描模板文件,更不会让浏览器报错——它只是终端里一行黄色文字,没人看就等于没存在。
必须把废弃逻辑收口到 @function 才能稳定触发 @warn
直接在 CSS 规则里写 @warn 是无效的(Sass 不允许在样式块顶层使用),正确做法是封装成带语义的函数:
@function legacy-btn-large() {
@warn "btn-large 已废弃,请改用 .btn.size-large";
@return (
padding: 1rem 2rem,
font-size: 1.125rem
);
}
.btn-large {
@include apply-map(legacy-btn-large());
}
-
@function确保调用路径可追踪,IDE 补全时会显示legacy-前缀,比注释更早提醒开发者 - 返回 map 而非直接输出 CSS,方便后续批量替换为新 utility 类生成逻辑
- 避免用
@mixin封装,因为@include不返回值,无法链式控制或统一拦截 - 函数名必须含
legacy-或deprecated-,否则 CI 或 grep 难以自动识别和审计
Webpack/Vite 项目里 @warn 可能静默失效的几个关键点
写了 @warn 却没看到输出?大概率卡在这几个环节:
立即学习“前端免费学习笔记(深入)”;
-
sass-loader默认关闭警告输出,需显式配置sassOptions: { verbose: true } - Vite 项目中
@warn只出现在终端构建日志,**不会输出到浏览器控制台** - CI 脚本用了
sass --quiet或重定向 stdout(如> /dev/null),警告直接被吞掉 - 用的是旧版
node-sass@4.x:插值语法@warn "xxx #{$val}"会直接编译失败,得写成@warn "xxx " + $val - 警告写在未被引用的
_utils.scss里,而该文件没被@import或@use,根本不会执行
真正起作用的组合:@warn + PostCSS 插件扫描 HTML
单靠 @warn 无法覆盖 HTML 层,必须补位:
- 用
postcss-html+ 自定义插件,在构建阶段扫描所有.html、.vue、.jsx文件,匹配已登记的废弃类名(如btn-large) - 插件报错信息能精确到文件名+行号,比 SCSS 里的
@warn更易定位 - 把废弃类名单独维护在 JSON 配置里,和 SCSS 函数中的提示保持同步,避免两边脱节
- CI 流程中将 PostCSS 扫描设为必过项,而不仅是警告——这才是“禁用”的实际约束力
最麻烦的从来不是写一句 @warn,而是确保它出现在开发者每次保存文件、每次提交、每次 CI 构建时都绕不开的路径上。否则,它只是日志里一闪而过的噪音。


















