根本原因是模块系统是否启用——混用@import与@use会使文件退化为legacy模式,导致样式拼接、变量作用域、输出顺序全部失效;@import是文本粘贴,@use是模块加载且强制命名空间隔离。

根本原因不是语法差异,而是模块系统是否启用——只要混用或误用,整个文件立即退化为 legacy 模式,所有样式拼接、变量作用域、输出顺序规则全部失效。
@use 和 @import 的底层行为完全不同
@import 是文本粘贴:把目标文件内容原样塞进当前上下文,所有 $variable、@mixin、CSS 规则都平铺到全局;@use 是模块加载:只导入符号(变量/mixin/函数),不自动输出 CSS,且强制命名空间隔离。
- @import "button" → 编译时直接展开 _button.scss 里的 .btn { ... },并插入当前位置
- @use "button" → 即使 _button.scss 里写了 .btn { ... },也不会产出任何 CSS;必须手动 @include button-styles() 才会生成
- @use "colors" as c 后,c.$primary 必须带前缀访问;而 @import "colors" 后,$primary 直接可用,但可能被后续同名变量覆盖
混用 @import 就等于关闭模块系统
哪怕只有一行 @import,Dart Sass 也会把当前文件及其整个依赖链降级为 legacy 模式——此时所有 @use 声明失效,命名空间消失,v.$color-text 报 Undefined variable,且样式插入位置完全失控。
- 错误示例:
@use "vars" as v下面紧跟@import "reset"→ 整个文件退化,v.$color-text必报错 - 第三方库如 bootstrap@5.2 内部仍用 @import,一旦你
@use "bootstrap",它内部的 @import 会拖垮你的整个依赖树 - 构建配置中隐藏的注入也很危险:vite.config.ts 的
sassOptions.additionalData若含@import,每个 SCSS 文件都会被单独降级
嵌套 @media 在两种模式下表现截然不同
在 @use 模式下,嵌套 @media 不影响最终 CSS 顺序,因为它不自动输出规则;但在 @import 或降级后的 legacy 模式下,嵌套 @media 会被 inline 到导入点,而 Dart Sass 会按依赖图重排,导致 @media (min-width: 768px) 出现在 @media (min-width: 480px) 后面。
- 真正可控的方式:删掉所有组件文件里的嵌套
@media,只在入口index.scss中手写顶层@media块,并严格按 min-width 升序排列 - 若某处用了
@import "mixins",哪怕只是引入一个@mixin,也会让该文件里所有嵌套@media失去位置控制权 - 编译后选择器权重也会飙升:.card {@media{&__title{}}} 展开为
.card @media{.card__title{}},而非预期的@media{.card__title{}}
最容易被忽略的是:问题往往不出在你写的主文件,而藏在被 @import 的某个 _utils.scss 里,或者 node_modules 中一个未升级的依赖里。定位必须全局搜索 @import,连单引号、双引号、路径别名、构建配置都不能漏。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











