新版Sass编译循环内@extend指令卡住 node-sass可正常编译
问题原因
新版Dart Sass(即npm上的sass包)对@extend的选择器匹配逻辑和旧版node-sass(LibSass)存在差异:你的代码中@extend .half写在嵌套选择器&.value-#{$i}.half内部,Sass在做选择器合并时,会递归匹配所有层级包含.half的选择器——包括当前父选择器链上评分容器挂载的.half类,触发无限循环的选择器回溯计算,最终表现为编译器卡住、无任何报错输出。添加!optional标记只能解决「找不到匹配选择器时报错」的问题,无法终止这种递归匹配逻辑,因此没有效果。
修复方案
你要继承的.half是挂载在.star子元素上的半星样式类,和外层评分容器的.half类不是同一个目标,只需要把@extend的目标选择器写精确,缩小匹配范围,避免匹配到外层容器的.half即可,这是改动最小的修复方式:
// 相关默认变量保持不变 $minRatingValue: 1 !default; $maxNumOfStars: 6 !default; @for $i from $minRatingValue through $maxNumOfStars { &.value-#{$i}.half { .star-container { @if ($i < $maxNumOfStars) { .star:nth-child(#{$i+1}) { // 原写法 @extend .half; 改为精确匹配.star元素上的half类 @extend .star.half; } } } } }
如果后续还出现类似匹配范围问题,更稳妥的长期兼容方案是把半星公共样式抽成@mixin复用,完全避开@extend的跨作用域匹配逻辑,不会因为选择器嵌套层级变化触发同类问题:
// 抽离半星公共样式为mixin @mixin half-star { // 此处放原.star.half类下的所有半星样式规则 } // 原有半星类直接引用mixin .star.half { @include half-star; } // 循环中直接调用mixin,不再使用@extend @for $i from $minRatingValue through $maxNumOfStars { &.value-#{$i}.half { .star-container { @if ($i < $maxNumOfStars) { .star:nth-child(#{$i+1}) { @include half-star; } } } } }
内容的提问来源于stack exchange,提问作者billyjov
相关产品推荐
相关产品推荐

