dart sass 1.69–1.77 编译差异源于ast遍历逻辑收紧,核心影响@mixins展开位置、@import/@use混用及&嵌套展开顺序;修复须同步调整这三处。

直接结论:Dart Sass 1.69 到 1.77 的编译差异不是 bug,而是 AST 遍历逻辑收紧导致的 CSS 输出顺序变化,核心影响点是 @mixin 展开位置、@import/@use 混用和嵌套中 & 的展开行为——修复必须从这三处入手,不能靠“回退版本”或“加 hack 注释”。
为什么 @mixin 生成的 CSS 突然“跳位”了
Dart Sass 1.77+ 对 AST 的深度优先遍历更严格,@mixin 不再按定义位置归类输出,而是严格按 @include 在源码中的嵌套层级插入。比如:
.card {
@include font-sm;
padding: $spacing-md;
}
过去可能把所有 font-size 规则聚在顶部;现在它会紧贴 .card 块内部输出,中间可能被其他组件样式打断。
- 高频复用的
@mixin(如reset-text、flex-center)尽量改写为@function,用内联值替代规则生成:font-size: typography.font-sm(); - 若必须保留
@mixin,统一收口到一个注入点文件(如base/_inject.scss),并在所有样式前@use它,避免分散@include - 别在
@mixin内部嵌套@media或&:hover—— 拆成独立@mixin更可控,也更符合新遍历逻辑
@import 和 @use 混用直接打乱依赖时序
@import 是扁平合并,@use 是作用域隔离,混用会让编译器无法判断变量/混合器的真实依赖链。典型场景:
// main.scss @use 'base/variables'; @import 'components/button'; // button.scss 内部又 @import 'base/mixins'
此时 button 的 CSS 可能被提前注入,因为它绕过了 @use 的声明顺序控制。
- 全项目立即弃用
@import,Dart Sass 1.77+ 已标记其为 deprecated,3.0.0 起直接报错 -
@use必须放在文件最顶部,且按依赖层级排序:variables→mixins→components - 组件需覆盖基础变量时,用
@use 'base/variables' with ($spacing-unit: 12px),禁止在组件里重定义同名变量
嵌套中 & 多次展开导致选择器“错行”
带 & 的嵌套(如 .btn { &--primary {}, &.is-loading {} })在 1.77+ 中会生成多个严格按源码顺序排列的同级节点。如果书写顺序和预期输出顺序不一致,CSS 就会“跳位”。
- 检查所有含多个
&的嵌套块,确认它们的书写顺序是否与你期望的 CSS 产出顺序一致 - 避免跨文件依赖同一父选择器的
&展开 —— 比如_header.scss和_nav.scss都写header { &__title {} },它们的输出位置将取决于各自文件被@use的顺序 - 对关键布局组件,改用 BEM 命名(如
header__title)替代嵌套,既规避顺序问题,也提升可维护性
最容易被忽略的是:这些变化不是孤立发生的。一个 @mixin 位置偏移,往往是因为它所在的文件被 @import 混入了依赖链,又恰好和某个 & 展开块处在同一 AST 深度——得同时看三者,不能只盯某一行代码。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











