大型团队用Less维护设计系统,核心在于变量全局收口、嵌套限两层内、mixin仅作带默认值的文本替换,以轻约束保障协作稳定性,前提是接受“编译期即定型”。

大型团队用 Less 维护设计系统,不是因为语法多酷,而是它在变量收口、嵌套可控、mixin 文本替换这三点上,能用最轻的约束换来最稳的协作节奏——前提是团队愿意接受“编译期即定型”这个前提。
变量必须全局收口且仅 @import 一次才不漂移
设计系统里颜色、间距、z-index 这些值一旦散落在多个 variables.less 文件里,@color-primary 就会变成薛定谔的颜色:A 模块引入了 theme-dark.less,B 模块没引,但都用了 @color-primary,编译后一个蓝一个灰,没人报错,只有上线后 QA 截图发群。
- 所有变量强制定义在
base/variables.less,路径写死,CI 加校验:grep -r "@color-primary" src/ | grep -v "base/variables.less"有输出就拒合 - 禁止在组件文件里
@import "variables.less",只允许根文件index.less统一引入,顺序固定为:variables→mixins→reset→components -
@color-primary这种命名必须带语义前缀,禁用@blue或@main-color;值类型统一为无单位数字或十六进制,不混用10和10px,否则@spacing-sm + 2编译直接崩
嵌套限两层内 + 显式父子选择器防特异性失控
Less 嵌套不报错,但编译出的 .card .header .title .icon 权重高达 4000,压得过所有第三方组件库的 .btn-icon,最后只能靠 !important 救火——这不是写样式,是在给未来埋雷。
- 嵌套严格限制在两层内,如
.card { &__header { ... } }可以,.card { &__header { &__title { ... } } }禁止 - 涉及 DOM 结构依赖的样式,必须显式写出父子关系:
.card-header-title-icon或.card > .header > .title > .icon,禁用模糊后代选择器.card .title .icon - 伪类和状态类可用
&:hover、&.is-active,但禁止& ul li a这种跨级写法,它等价于宽松匹配,极易污染其他模块
Mixin 只做文本替换,别塞逻辑
.btn(@bg, @color, @hover-bg) 看似灵活,实则让调用者每次都要查文档记参数顺序;更糟的是,有人传错类型(比如把字符串当数字),Less 静默忽略,CSS 输出里直接消失——你得肉眼比对生成结果才能发现漏了 hover 色。
立即学习“前端免费学习笔记(深入)”;
- 所有 mixin 必须设默认值,哪怕只是
~""或initial,防止未传参时报undefined variable - 参数超过 3 个就拆:用
.btn-base()定基础样式,再配.btn-primary()、.btn-secondary()等语义化变体 - 需要条件分支?别硬塞进一个 mixin,宁可多建两个,也别写
.btn(@type) when (@type = primary) { ... }—— Less 的when不是运行时判断,是编译期展开,维护成本反而更高
真正卡住大型团队的,从来不是写一行样式有多慢,而是改一个 @spacing-sm 后,得花二十分钟确认:有没有哪个子模块偷偷重定义了它?有没有哪个 @import 顺序错了导致主题失效?有没有哪个嵌套层级超限让权重爆炸?Less 不提供银弹,但它用极简的规则边界,把这些问题逼到明面上来处理。


















