@import必须淘汰,因其线性拼接无作用域,同名变量/mixin静默覆盖;@use强制命名空间隔离、单次引入、编译期报错依赖缺失,且禁循环引用。

大型企业级管理系统里,SCSS 不是用来“写得更短”,而是用来“改得更稳”——变量必须语义化分层、@use 替代 @import、所有基础能力必须在 base/ 和 utils/ 里收口,否则换肤、多品牌、无障碍适配都会在第 3 次迭代时崩盘。
为什么 @import 在企业项目中必须淘汰
旧式 @import 是线性拼接,没有作用域,变量和 mixin 一旦重名就静默覆盖;@use 强制命名空间隔离,且只允许单次引入,编译器能提前报错未声明的依赖。
-
@import "mixins"后,@include button-style直接可用,但若另一个@import "legacy/mixins"也定义了同名button-style,后者无警告覆盖前者 -
@use "mixins" as btn后,必须写@include btn.button-style,调用点即暴露来源,重构时可精准定位引用 -
@use不支持循环引用,Dart Sass 会直接报错,而@import可能编译成功但样式错乱(比如$z-index-modal被components/dropdown里的同名变量覆盖) - 迁移时注意:
@use中的变量默认私有,需加!public才能被其他模块读取,例如$color-primary: #2563eb !default !public;
base/ 和 utils/ 的职责边界在哪
混淆这两层是企业项目样式失控的起点。base/ 是 CSS 运行时基础设施,utils/ 是 SCSS 编译期工具链——前者决定浏览器渲染结果,后者只影响编译输出。
-
base/_reset.scss:仅含*, *::before, *::after { box-sizing: border-box; }和html { font-size: 100%; },不出现任何变量或 mixin -
base/_variables.scss:只放根级 CSS 自定义属性,如:root { --color-primary: #2563eb; --spacing-md: 1rem; },不定义 SCSS 变量$color-primary -
utils/_variables.scss:定义$color-primary: var(--color-primary) !default;,供 SCSS 层消费;所有断点 map、阴影 token 都放这里 -
utils/_functions.scss:只写纯函数,如@function color($name) { @return map-get($colors, $name); },禁止副作用(不修改全局变量、不输出 CSS)
主题切换时,SCSS 变量和 CSS 变量怎么协同不打架
直接用 SCSS 变量做主题切换,等于把构建时决策拖到运行时——每次换肤都要重新编译整包 CSS。正确做法是 SCSS 只管结构,CSS 变量管状态,两者通过 var() 桥接。
立即学习“前端免费学习笔记(深入)”;
- 组件内写
background-color: var(--color-primary);,而非background-color: $color-primary;,确保 JS 切换document.documentElement.style.setProperty('--color-primary', '#3b82f6')立即生效 - SCSS 层只做一层映射:
$color-primary: var(--color-primary) !default;,让@mixin button-variant这类逻辑仍可用 SCSS 函数计算(如lighten($color-primary, 10%)),但最终输出仍是var(--color-primary) - 避免在
:root里用!important覆盖变量值,DevTools 里无法追踪源头;主题 CSS 文件应通过<link rel="stylesheet" media="(prefers-color-scheme: dark)">加载,靠媒体查询优先级控制 - 深色模式下
color: var(--color-text-primary)失效?检查父元素是否漏设--color-text-primary——CSS 变量不继承,必须逐层设置或用inherit显式传递
为什么 !default 只能在基础库用,业务层必须显式重赋值
!default 看似方便,实则掩盖依赖关系。企业项目里,一个变量被多少个 @use 模块间接引用,根本无法静态分析。
-
utils/_variables.scss中:$font-size-base: 1rem !default;—— 允许下游覆盖 -
themes/_dark.scss中:$font-size-base: 0.95rem;(不加!default)—— 明确意图 -
components/_table.scss中:font-size: $font-size-base;—— 直接使用,不加判断 - 禁止在业务组件里写
$font-size-base: 1.1rem !default;,否则当themes/_dark.scss和该组件同时被引入,Dart Sass 会因重复赋值报错 - 真正难的不是语法,是团队约定:所有主题覆盖必须集中到
themes/目录,且每个主题文件必须完整声明所有可变变量,不能只改其中几个


















