大型项目用 Sass 的核心是明确变量、mixin 和样式的归属与调用路径;需按需导入、避免循环依赖、合理使用 @forward 和 with、控制嵌套深度、规范 BEM 命名、正确配置第三方包路径,并钉死定义与调用链路。

大型项目里用 Sass 组织 CSS,核心不是目录套几层,而是让每个变量、mixin、样式块都有明确归属和调用路径;照搬“7-1架构”但把 _button.scss 放进 utils/ 或在 components/ 里定义 $spacing-lg,反而加速失控。
入口文件必须只 @use 所需模块,不能偷懒写 @use "components"
多个页面入口(如 admin.scss、checkout.scss)如果都 @use "sass/components",构建工具默认会在每个输出 CSS 中重复生成全部组件样式——哪怕某个页面只用按钮。
- ✅ 正确做法:按需导入,例如
@use "sass/elements/button"、@use "sass/layout/grid" - ⚠️ 错误信号:
components/目录下出现_variables.scss或_mixins.scss—— 这些该在utils/或base/里 - ❌ 禁止在
@use链路中循环依赖,Dart Sass 会直接报Circular dependency,不提示具体哪一行
@forward 要建“接口层”,不是把所有东西 re-export 出来
@forward 的作用是统一出口,避免每个组件都重复写一长串 @use;但它不是“打包转发”,而是有选择地暴露能力。
- ✅ 推荐写法:
@forward "utils/breakpoints" as bp-*→ 外部调用bp-max('md'),命名空间清晰可追溯 - ⚠️ 避免
@forward "utils" as *—— 一旦utils/_functions.scss和utils/_mixins.scss都定义了em(),冲突无声发生 - ? 用
with覆盖默认值:@forward "vars" with ($font-size-base: 16px),但必须在@use之前完成
嵌套深度超过 3 层就该警觉,BEM + 平铺比 & 嵌套更可控
Sass 嵌套是语法糖,最终输出的 CSS 选择器权重和匹配成本由浏览器承担。`.page .section .block .block__item:hover` 比 `.block__item:hover` 多两次祖先回溯,Lighthouse 的 “Recalculate Style” 时间会明显上升。
立即学习“前端免费学习笔记(深入)”;
- ✅ 推荐写法:用 BEM 命名平铺,
.block__item、.block__item--active,靠引入顺序控制优先级 - ❌ 禁止写:
.block { &__item { &:hover { } } }再套一层@media—— 这已超 3 层 - ⚠️
&用于 BEM 时必须严格:&__item、&--large,禁用& .child或& > span,否则破坏原子性
第三方包必须配 includePaths,别手写 node_modules 路径
Dart Sass 默认不查 node_modules,直接写 @use "node_modules/bootstrap/scss/functions" 必报错;而且 Bootstrap 5 虽支持 @use,但它的 @forward 结构很绕,容易漏掉 show 列表。
- ✅ Webpack 用户:在
sass-loader配置中加includePaths: ['node_modules'] - ✅ Vite 用户:在
vite.config.ts中设css.preprocessorOptions.sass.includePaths = ['node_modules'] - ⚠️ Bootstrap 场景下,仅设
$enable-modals: false不够,必须跳过整行@use "bootstrap/modal",否则 mixin 仍可能被间接调用
真正卡住大型项目的,从来不是目录结构多两层,而是变量在哪定义、谁有权修改、某条 CSS 规则到底从哪个 @use 链路来——这些细节不钉死,越往后越难定位、越不敢动。


















