@use能真正隔离命名空间,因它强制成员必须通过文件名或as别名前缀访问(如colors.$primary),默认私有且不污染全局;而@import是文本拼接,同名变量必被后导入者静默覆盖,且重复解析导致冗余编译。

因为 @use 默认不把变量、混合宏、函数扔进全局作用域——它强制你加命名空间才能访问,从源头掐断了静默覆盖和意外读取。
为什么 @import 必然导致污染
@import 不是加载模块,是文本拼接。它把整个文件内容原样塞进当前作用域,没有任何边界检查:
- 两个文件都定义
$z-index-modal: 1000→ 后导入的直接覆盖前一个,DevTools 只显示最后一处位置 - 第三方库和你自己的
_mixins.scss都导出@mixin clearfix→ 编译器只认最后一个,行为不可控 -
@import "utils"在 5 个组件里各写一次 → Sass 解析 5 次同一文件,生成冗余 CSS,热更新变慢
@use 怎么做到真正隔离
@use 的隔离不是“建议”,是硬性规则:所有成员默认私有,必须显式通过命名空间访问。
-
@use "colors"→ 只能写colors.$primary,直接写$primary报错Undefined variable "$primary" -
@use "theme/dark" as dark和@use "theme/light" as light→dark.$bg和light.$bg完全独立,互不影响 - 连字符命名保持原样:
dark.$text-sm不能写成dark.$textSm,Sass 不做自动转换 - 重复
@use "utils"十次?只解析一次,后续复用缓存,无冗余
迁移时最容易踩的三个坑
不是把 @import 替成 @use 就完事——Dart Sass 的模块系统有硬性约束,错一条就编译失败:
立即学习“前端免费学习笔记(深入)”;
-
@use必须是文件中第一个非注释、非空行语句,不能包在@if、@media或选择器里,否则报Invalid CSS after "@use" - 路径不能带扩展名或下划线:
@use "src/styles/variables"✅,@use "src/styles/_variables.scss"❌ -
!default在@use下只生效一次,旧写法$primary: red !default在多个@import中可反复回退赋值,但@use加载后值就固定了
最常被忽略的是路径约定和命名空间显式性——漏掉一个下划线,或忘了给 @use 加 as 别名,变量就完全不可见,而且编译器不会提示“你可能忘了引用”,只会安静地报错或静默失效。


















