根本原因是@import、extend、mixin机制被误用或未收敛:@import多次引入同一文件导致内容重复;extend跨文件未导入或未加all导致静默失效;mixin调用多次则样式块重复展开。
Less 编译后出现重复 CSS,根本原因不是语法写错,而是 @import、extend、mixin 这三类机制被误用或未收敛——它不会自动 dedupe,所有“重复”都是你写的结构在编译期被忠实展开的结果。
Less 不做依赖去重,@import "mixins.less" 写三次,就插入三次内容。尤其当多个组件文件各自 @import 同一工具文件时,变量、mixin、extend 基类全被复制多遍。
@import (once) 替代裸 @import,但注意:路径必须完全一致("./utils" 和 "utils" 被视为不同文件)@mixin、@function、变量统一收口到单个入口文件(如 base.less),再由主入口 @import (once) "base.less"
@import "components/*.less" 在多数 Less 版本中不生效,且破坏依赖可追踪性strictImports: true(less-loader 配置或命令行),让缺失文件立即报错,避免静默跳过导致部分样式漏载extend 是编译期选择器合并,不是运行时去重。它只在目标选择器真实存在、且语法完全匹配时才生效;失效即静默,不会报错,但你会看到两个独立选择器。
@import 目标文件,否则 .btn-primary:extend(.btn) 直接编译失败(报错 “selector not declared”)@media、嵌套块或 mixin 动态生成结果里——extend 匹配的是最终输出的字符串,不是语义.btn:hover)时,必须加 all:.btn-primary:extend(.btn all),否则只合并顶层声明extend 处理带参数的变体;它不支持变量、伪类目标(如 .btn:hover:extend(.btn) 无效),该场景请用 mixin
mixin 是文本插入器,每次调用都完整展开全部声明。一个含媒体查询+伪类的复杂 mixin 被调用 10 次,就生成 10 份相同 CSS。
.clearfix()、.center())适合 mixin;含多层嵌套、断点、状态的,应拆成原子级小单元(.rounded-sm()、.shadow-xs())&:.card { &:hover { .transition() } } 正确;.card { :hover { .transition() } } 会输出全局 :hover,污染其他元素mixin 必须写空括号:.clearfix(),否则定义被当普通 class,调用时报 undefined mixin
mixin + 参数;主题切换、暗色模式等运行时响应场景,改用 CSS 自定义属性,mixin 只负责生成基础结构Less 编译器本身不压缩、不去重、不合并选择器。所谓“生产环境体积优化”,90% 靠 PostCSS 阶段完成,而不是 Less 配置。
lessc --clean-css,它只做基础压缩;把 CSS 输出交给 cssnano 或 clean-css 插件,它们能真正合并重复声明、移除冗余选择器cssnano),不能颠倒;否则 /* @preserve */ 注释或兼容性 hack 可能被误删merge 功能(less-loader 中设 math: 'strict'),它试图合并相邻规则,但易出错且与 PostCSS 冲突@import "https://cdn.example.com/normalize.less")会阻塞构建、增加不可控依赖,一律改为本地 @import (reference) 或复制到项目内最常被忽略的一点:重复 CSS 往往不是某一行代码写错了,而是整个导入链和复用策略没收敛。检查 main.less 的 @import 树,比盯着某一个 mixin 更有效。