@use是唯一能真正切断污染链的语法,因它强制创建私有命名空间,所有变量和mixin必须显式加前缀访问(如v.$font-size-base),而@import本质是作用域合并,导致同名成员静默覆盖、IDE跳转失效、重复编译及CSS冗余。

@use 是唯一能真正切断污染链的语法,继续用 @import 就等于默认接受变量覆盖、mixin 冲突和重复编译。
为什么 @import 一定会导致命名空间污染
@import 不是“引入”,是“作用域合并”——它把所有 $variable、@mixin、%placeholder 全部平铺进当前文件,不加前缀、不设边界。一旦两个模块都定义了 $spacing-sm,后 @import 的那个直接覆盖前者,且编译器不报错、IDE 跳转失效。
- 多个组件库同时
@import "sass:map",可能因函数名冲突导致map-get()行为异常 -
@import "button"和@import "card"都含@mixin shadow(),最终只保留后者,但调用方完全不知情 - Webpack/Vite 中重复
@import "_reset.scss",会输出多份重置样式,体积膨胀且优先级混乱
@use 怎么强制隔离变量和 mixin
@use 默认创建私有命名空间,所有成员不可见,必须显式带前缀访问。这不是可选项,是 Sass 编译器的硬性约束。
- 写
@use "base/vars" as v,就必须用v.$font-size-base,直接写$font-size-base会报错Undefined variable - 同一文件多次
@use "utils/functions"不会重复执行,Sass 内部自动去重 - 第三方模块如
sass:math必须写@use "sass:math",不能混用@import "sass:math" - 想全局解构?只允许
@use "base/vars" as *,且该文件不能含任何@mixin或样式规则
为什么 %placeholder 比 @mixin 更适合基础样式复用
%placeholder 天生不输出 CSS,只在 @extend 时按需注入,既规避样式膨胀,又杜绝“未调用却已污染”的风险。
立即学习“前端免费学习笔记(深入)”;
-
@mixin reset { margin: 0; padding: 0; }被调用 12 次,就生成 12 份相同规则;%reset { margin: 0; padding: 0; }+@extend %reset只输出一次 -
%sr-only不会意外匹配 HTML 中的class="sr-only",因为它根本不会出现在最终 CSS 里 - 跨文件使用必须先
@use或@forward进当前作用域,天然受模块系统约束 - 禁止对插值选择器使用
%,例如.u-p-#{$n}里不能@extend %p-#{$n},Sass 会报错"%placeholder is not a valid selector"
@forward 如何精准控制模块暴露内容
当你封装一个组件模块(如 _card.scss),又不想把内部实现细节(比如 $_card-private-token)暴露出去,@forward 是唯一可控手段。
-
@forward "card" show $size-large, @mixin card-hover—— 只透出指定成员,其余自动隐藏 -
@forward "card" hide $_private-token—— 显式过滤敏感内部变量 -
@forward "card" as card-→ 下游必须写card-$size-large,彻底切断命名耦合 - 若模块内部依赖其他
@use的文件,@forward不会自动透出那些依赖,必须显式转发
真正难的不是写对 @use,而是改掉旧习惯:不再把所有变量倒进一个全局桶里,也不再指望靠命名约定(比如 $btn-primary-color)来防冲突。模块化不是加个前缀,是让每个文件默认闭合、显式开放。


















