真正能扛住十万行CSS的方案是@use+明确模块边界+禁用@import;否则变量泄露、样式重复、构建失控将不可避免。

十万行 CSS 工程里,靠手写、全局搜索、复制粘贴改颜色,三天就能崩溃。真正能扛住的方案只有一条路:@use + 明确的模块边界 + 严格禁止 @import。其他所有“结构美观”“目录整齐”的做法,只要没切断变量泄露和样式重复,规模一上五位数就必然失控。
为什么7-1目录结构在十万行项目里反而危险
7-1(base/components/layout等7个目录+1个main.scss)不是性能或编译优化方案,它只管人怎么协作。但十万行项目里,人已经不是瓶颈——构建速度、CSS体积、调试定位才是。常见翻车点:
-
@import "base/variables"放在@import "components/button"后面 → 编译直接报Undefined variable "$color-primary" -
components/_modal.scss里偷偷定义了$z-index-overlay: 9999→ 全局污染,_tooltip.scss的 z-index 被静默覆盖 - 所有入口文件(
admin.scss、checkout.scss、dashboard.scss)都@use "components"→ 最终打包出三份完全一样的 button 样式,体积翻倍
@use 链路必须收敛到单一入口文件
每个功能域(如 components/、themes/)必须配一个 _index.scss,里面只做两件事:用 @use 加载子模块,用 @forward 暴露公共 API。不能写任何样式规则,不能定义新变量。
例如 components/_index.scss:
立即学习“前端免费学习笔记(深入)”;
@use 'button' as btn; @use 'card' as card; @use 'form' as form; @forward 'button' as btn-*; @forward 'card' as card-*; @forward 'form' as form-*;
这样下游才能干净地写 @use 'components' as comp;,且 comp.$btn-size-lg 和 comp.$card-radius-sm 不会撞名。一旦漏掉 @forward 或混入 @import,整个链路就退化成全局作用域,tree-shaking 失效。
组件文件内严禁嵌套超过3层 & 禁止跨组件引用
嵌套不是为了“看起来像 DOM”,而是为了表达组件内部结构。超3层就等于生成冗余选择器,浏览器匹配变慢,Lighthouse 报告里 “Avoid large layout shifts” 会频繁亮红灯。
- ❌ 错误:
.page { .section { .block { &__item { } } } }→ 输出.page .section .block .block__item,权重高、难覆盖 - ✅ 正确:
.block__item { }+ BEM 命名,靠引入顺序控制优先级 - ⚠️ 绝对禁止:
_button.scss里@use '../layouts/grid'—— 组件只消费utils/和base/提供的能力,不依赖其他组件
构建时必须显式控制 CSS 分片与压缩
Sass 本身不拆包,@use 只解决作用域,不解决产物体积。十万行项目里,这三件事不做,编译后 CSS 动辄 800KB+:
- Webpack/Vite 必须开启
cssCodeSplit或splitChunks,让button.css、grid.css分离加载 - Dart Sass 编译命令必须带
--style=compressed,否则保留空格、换行、注释,体积膨胀 2–3 倍 - 禁用
@extend—— 它在多入口场景下会把同一段样式复制进每个输出文件;改用@mixin+@include,构建工具能识别并复用
最常被忽略的是:哪怕只在一个 .scss 文件里残留一行 @import "reset",整个 @use 链路就会降级,所有模块失去作用域隔离,变量冲突、样式重复、调试失焦问题全部回归。


















