@use是Sass工程化刚性门槛,因它强制模块化隔离:变量/混合宏/函数默认私有,须显式命名空间访问(如vars.$color),杜绝@import的全局污染、隐式覆盖与重复编译。

@use 是当前 Sass 工程化维护的底线要求,不是“可选优化”,而是避免变量冲突、命名污染和编译失败的刚性门槛。旧项目还在用 @import 全局拼接,迟早会遇到样式覆盖不可追溯、第三方库混用报错、CI 构建突然失败等问题。
为什么 @use 必须替代 @import?
根本原因不是语法新旧,而是作用域模型完全不同:@import 把所有内容 flat 合并进全局作用域,@use 强制封装 + 显式暴露。这意味着:
- 变量、混合宏、函数不再自动泄漏到其他文件——比如
_variables.scss里的$color-primary,不通过@use "variables" as vars就根本访问不到 - 重复
@use "theme"会直接报错"theme" has already been loaded,而不是静默覆盖,这能立刻暴露循环依赖 -
@use加载的第三方库(如sass:math)必须写成@use "sass:math",@import "sass:math"在 Dart Sass 1.23+ 中已彻底失效 - 路径解析失败时,错误信息明确指向 “couldn’t resolve import”,而不是编译后 CSS 错乱再倒查——这对 CI/CD 非常关键
@use 的路径和命名空间怎么写才不踩坑?
路径必须是相对路径或基于 includePaths 配置的别名,不能是 URL 或绝对系统路径;命名空间则决定你后续如何引用变量和混合宏:
- 写法
@use "components/button" as btn→ 变量用btn.$primary-padding,混合宏用@include btn.hover-effect() - 省略
as时,命名空间默认为文件名(不含扩展名),@use "utils"→utils.$z-index-base - 想把某个模块所有成员直接挂到全局?可以
@use "variables" as *,但仅限入口文件(如index.scss),且禁止在 partial 文件里用,否则破坏模块边界 - 路径以
_开头的文件(如_mixins.scss)不会被单独编译,只能靠@use引入,这是强制“不暴露”的设计
第三方库(如 Bootstrap)怎么安全接入?
直接 @use "bootstrap/scss/bootstrap" 会把所有 CSS 规则注入全局,这不是作用域问题,而是 CSS 本身限制——Sass 层面无法封装已生成的选择器。所以关键不是“能不能引入”,而是“要不要让它生效”:
- 只复用逻辑:用
@use "bootstrap/scss/functions" as bs-fn拿它的bs-fn.color-contrast(),不触发任何 CSS 输出 - 按需加载组件:不要
@use "bootstrap/scss/bootstrap",改用@use "bootstrap/scss/mixins"+@use "bootstrap/scss/utilities",再手动@include所需部分 - 绝对不要在
.my-app { @import "bootstrap" }这种嵌套块里加载第三方 CSS——它既不能真正隔离样式,又可能破坏 JS 绑定(比如 Bootstrap 的data-bs-toggle依赖原生类名) - 如果必须用完整 CSS,就走纯 CSS 方式:在 HTML
<link>中引入,或 Webpack 中用css-loader单独处理,和 Sass 代码物理隔离
迁移旧项目时最常卡住的三个点
不是语法不会写,而是旧逻辑和新规则硬碰撞:
立即学习“前端免费学习笔记(深入)”;
-
@import和@use不能共存于同一文件——哪怕只是@import "old-vars"; @use "new-mixins",Dart Sass 也会拒绝编译,报错 “cannot mix @import and @use” - 原来靠
@import隐式传递的变量,现在必须显式@use并带上命名空间,否则编译时报Undefined variable - 第三方库的
@forward声明(如 Bootstrap 5 的_forward.scss)只对@use生效,@import完全无视,导致升级后部分 mixin 突然找不到
@use 语法,而是接受“没有全局作用域”这个前提——所有变量、函数、混合宏都必须声明来源,所有依赖都得白纸黑字写清楚。一旦习惯这种显式契约,样式维护就从“猜谁改坏了”变成“看导入链就能定位”。


















