大型 Sass 项目目录结构的核心是控制声明顺序与作用域:base/ 存根级样式和重置,utils/ 存纯逻辑(变量/mixin/函数),components/ 仅消费前两者;@use 要求严格路径、命名和位置,错位即编译失败。

大型 Sass 项目里,目录结构不是为了“看起来整齐”,而是为了控制变量、mixin、样式的可见范围和加载顺序——放错一个文件,@use 就失效,$spacing-sm 就 undefined,@include respond-to 就报错。
为什么 7-1 架构的目录顺序不能调换
SCSS 编译是线性拼接,不是模块解析。变量、函数、mixin 必须先声明后使用,否则直接编译失败。
-
base/variables.scss必须在base/mixins.scss之前,因为 mixin 常依赖$breakpoints或$radius-md -
utils/functions.scss必须在所有用到它的mixins或components之前,否则@function em($px)调用时报 undefined -
vendor/(如 normalize.css)必须在base/reset.scss之前,否则第三方样式会覆盖重置规则 -
pages/必须放在最后——它只做局部覆盖,不提供基础能力,提前引入会导致样式被 base 层覆盖
base/ 和 utils/ 的职责边界在哪
这两个目录最容易混淆,但分不清就会导致逻辑污染和复用断裂。
-
base/是根级基础设施:只放_reset.scss、_typography.scss、:rootCSS 变量声明。禁止出现任何组件名(如.card)或业务语义类 -
utils/(也叫abstracts/)是纯逻辑层:只存_variables.scss(断点 map、主题色 map)、_mixins.scss(@mixin respond-to)、_functions.scss(@function em)。它不写一行真实样式 - ❌ 错误:
utils/_mixins.scss里定义@mixin card-shadow—— 这属于components/card.scss的职责 - ✅ 正确:
components/_button.scss里用map-get($shadows, sm)+@include respond-to(md)
@use 要求的文件命名与路径规范
@use 不是字符串替换,它按约定查找文件,路径或命名稍有偏差就加载失败。
立即学习“前端免费学习笔记(深入)”;
- 路径不带扩展名和下划线:
@use "utils/variables"自动匹配_variables.scss,写成@use "utils/_variables.scss"会报错 - 命名空间默认取文件名:
@use "utils/breakpoints"→ 外部用breakpoints.max('md');重命名用@use "utils/breakpoints" as bp→bp.max('lg') -
@use必须在文件最顶部,不能嵌套在@media、选择器或@if内部,否则编译直接中断 - 慎用
as *:@use "utils/variables" as *会把所有变量平铺进当前作用域,失去来源追踪,仅限极小工具库临时使用
components/ 文件粒度与嵌套陷阱
每个 _xxx.scss 文件应对应一个视觉上可独立存在的 UI 单元,但过度嵌套会让权重失控、调试困难。
- 一个文件只负责一个组件的全部样式:结构(BEM 命名)、状态(
&.is-active)、响应式(@include respond-to(sm)) - 禁止跨组件引用:
components/_modal.scss不能@use "components/button",应通过utils/提供的变量和 mixin 组合实现 - 避免深层嵌套:
.header { .nav { &__item { } } }编译后是.header .nav .nav__item,权重高、难覆盖;改用平铺写法.nav__item更可控 - 禁止在
components/中定义新变量或 mixin——它们只消费utils/和base/提供的能力
真正卡住大型项目的,从来不是语法不会用,而是 main.scss 里一行 @use 的位置错了,或是 utils/_variables.scss 里一个 $font-size-base 没加 !default 导致第三方包无法覆写——这些细节没有 warning,只有编译失败或运行时样式错乱。


















