!default不是CSS变量的fallback,而是编译期一次性声明守门员;它仅在变量首次声明前生效,顺序错则完全失效,且被Webpack modifyVars等注入方式绕过,必须前置声明并分层管理变量文件。
很多人把 !default 当成 var(--color, #1890ff) 的 Less 版本,结果改了深色主题却没生效——根本原因是它不参与运行时计算,只在变量**首次落定前**起作用。一旦前面某处写了 @primary-color: #333;,后面所有 @primary-color: #ff6b6b !default; 全部失效,连警告都没有。
常见错误现象:themes/dark.less 里写了 @primary-color: #ff6b6b !default;,但项目入口先 @import 'base.less',而 base.less 里已有 @primary-color: #333; ——此时 !default 彻底被跳过,深色主题根本不会覆盖。
!default 必须出现在所有可能的首次赋值之前,顺序错就等于没写@spacing: @spacing * 2 !default;,右侧引用未落定变量会报 Recursive variable definition
modifyVars(如 { '@primary-color': '#52c418' })是字符串级注入,直接绕过 !default 逻辑,两套配置必须手动同步你以为变量在 dark.less 里声明了就能生效?实际编译器只认“谁先占坑”。
button.less)里重复 @import 'variables.less':导入顺序混乱,导致同一变量被多次声明,!default 只对第一次有效!default 塞进 .mixin 里:Mixin 作用域内变量解析不稳定,容易漏掉或误覆盖@color: ; 已构成一次声明,后续 @color: red !default; 直接忽略别跟 !default 死磕,它只适合做“基础库兜底”,不适合做“主题开关”。
vars-base.less,只放带 !default 的初始值:@primary-color: #1890ff !default;
vars-user.less(或由构建脚本生成),写无 !default 的强制赋值:@primary-color: #ff6b6b;
@import:@import 'vars-base.less'; @import 'vars-user.less'; @import 'components/button.less';
!default 不输出任何 CSS,但它像一个隐形开关,控制着后续所有基于该变量的计算是否走对分支。比如 @border-radius: 4px !default; 没生效,那所有 .btn { border-radius: @border-radius; } 都会用错值,而且你查 CSS 文件根本找不到线索——因为错误发生在编译期,源头藏在 import 顺序里。
最容易被忽略的点:node_modules 里的第三方 Less 库(比如 antd 的 theme 文件)如果也定义了同名变量,且 @import 顺序靠前,你的 !default 就会被截胡,连 debug 都难定位。