@use是唯一能切断命名冲突链的语法,因它强制创建私有命名空间、要求显式前缀访问(如v.$font-size-base),而@import本质是无边界作用域合并,导致同名变量/mixin静默覆盖、CSS冗余及IDE跳转失效。

@use 是唯一能切断命名冲突链的语法,@import 本质是作用域合并,不是引入。
为什么 @import 必定引发类名/变量/mixin 冲突
@import 把所有 $variable、@mixin、%placeholder 平铺进当前文件,不加前缀、无边界。常见现象包括:
- 两个模块都定义了
$spacing-sm,后@import的直接覆盖前者,编译器不报错 -
@import "button"和@import "card"都含@mixin shadow(),最终只保留后者,调用方完全不知情 - Webpack/Vite 中重复
@import "_reset.scss",CSS 输出多份重置规则,体积膨胀且优先级混乱 - 多个组件库同时
@import "sass:map",可能因map-get()函数行为异常导致逻辑错乱
@use 如何强制隔离并避免污染
@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"会让整条依赖链降级为 legacy 模式 - 想全局解构?只允许
@use "base/vars" as *,且该文件不能含任何@mixin或样式规则
配合 & + BEM 生成真正隔离的选择器
仅靠 @use 能防变量/mixin 冲突,但不能解决 CSS 类名本身在 HTML 中的碰撞。必须结合嵌套与 & 显式绑定父级:
立即学习“前端免费学习笔记(深入)”;
- .card {
&__header{ font-size: 1.2rem; } } → 输出.card__header,不依赖 DOM 层级,也不怕被外部.header干扰 -
&必须紧贴选择器:& __header(中间有空格)会变成全局__header,完全失效 - 前缀建议用业务/组件名(如
auth-、dash-),避免泛化词如my-或custom- - 不要对动态插值类名(如
.u-mt-#{$n})用%placeholder,它不支持插值,会报"%placeholder is not a valid selector"
@forward 控制暴露粒度,防止内部细节泄漏
封装组件模块(如 _card.scss)时,@forward 是唯一可控手段,避免把 $_card-private-token 这类实现细节暴露出去:
-
@forward "card" show $size-large, @mixin card-hover—— 只透出指定成员 - 跨文件使用
%placeholder时,被继承的%必须已通过@use或@forward引入当前作用域 - 若第三方库未适配模块系统(如 Bootstrap 4),应将其包裹进独立 partial,并用
$prefix重命名 class 前缀(如$prefix: "bs4-") - 禁止对插值选择器使用
%,例如.u-p-#{$n}里不能@extend %p-#{$n},Sass 会报错
真正难的不是写对 @use 语法,而是团队里有人忘了删掉旧的 @import,或在某个组件里偷偷加了 @use "mixins/flex.scss" as *。模块化管不住人,只能靠 lint 规则和 CI 检查 @import 和裸 as * 的出现。


















