compressed模式不减语义体积,仅删空格换行注释;真正膨胀源于@mixin无节制展开、跨文件重复定义及循环中暴力生成;抽离未调用mixin反增体积,因Sass无tree-shaking;应按工具型/视觉型分类处理,优先用CSS自定义属性替代视觉mixin,禁用@each中调用含选择器的mixin,改用插值生成原子类并交purgecss裁剪;sassOptions.outputStyle须显式设为'compressed'且sourceMap: false;必须用@use替代@import实现按需导入,避免全量拼接;体积瓶颈在嵌套、@extend和重复逻辑,非格式冗余。

compressed 模式本身不会缩小语义体积 —— 它只删空格、换行、注释,不删重复规则、不剔未用类、不合并选择器。真正让 CSS 膨胀的,是 @mixin 被无节制展开、跨文件重复定义、或在循环中暴力生成。
为什么抽离 @mixin 反而可能增大体积
抽离本身不是目的,盲目抽离反而加重体积问题:
- 抽离后未被调用的
@mixin仍会参与编译(Sass 不做 tree-shaking) - 多个文件
@use同一个 mixin 文件,但只用其中 1 个@mixin,其余仍全量注入 - 若 mixin 内含嵌套、
@extend或动态选择器(如&.is-active),每次调用都会复制整块逻辑 - 常见错误现象:
main.css里出现 23 次一模一样的display: flex; flex-wrap: wrap;,查源码发现是@include flex-wrap()在 23 个组件里各自展开
建议做法:
- 把纯计算型、无副作用的工具
@mixin(如px2rem()、fluid-type())抽到tools/目录,用@use "tools/functions" as fn调用函数而非 mixin - 视觉型
@mixin(如card-base()、btn-variant())改写为 CSS 自定义属性驱动:用--card-padding+ 单一类名控制,声明只存一份 - 禁止在
@each循环里@include含选择器的 mixin;改用@for+#{}插值生成原子类,并交给purgecss裁剪
sassOptions.outputStyle 必须显式设为 'compressed'
Webpack 项目中,sass-loader 默认不启用压缩 —— 它只是把 Sass 编译成 CSS,格式由 sassOptions.outputStyle 控制。漏配这项,后续所有压缩插件(如 css-minimizer-webpack-plugin)都得处理 expanded 格式,白白多压一遍空格。
立即学习“前端免费学习笔记(深入)”;
配置位置必须准确:
- Vue CLI:写在
vue.config.js的css.loaderOptions.sass.sassOptions - Webpack:写在
module.rules对应sass-loader的options.sassOptions - 错误写法:
module.rules.sassOptions(顶层无效)、css.minimizer下配(太晚,Sass 已输出冗余)
同时必须关闭 sourceMap:
-
sourceMap: false,否则末尾追加的 base64 映射字符串可增加 100KB+ - 不要依赖默认值,某些 sass-loader@v13 版本默认开启 sourceMap
抽离 ≠ 共享:用 @use 替代 @import 才真能减体积
@import 是文本拼接,哪怕你只写 @include button-reset(),整个 mixins.scss 也会被完整塞进输出;@use 则支持按需导入,且强制命名空间,避免冲突。
典型对比:
- 错误:
@import "mixins"; @include font-sm(); @include spacing-xs();→ 整个 mixins 文件加载 - 正确:
@use "mixins" as m; @include m.font-sm(); @include m.spacing-xs();→ Dart Sass 可识别未使用模块并跳过部分解析
注意限制:
-
@use不支持条件导入(不能@if包裹@use) - 所有变量/mixin 必须加前缀(如
m.$spacing-xs),无法全局注入 - 若旧项目混用
@import和@use,Dart Sass 会报错,需统一迁移
真正卡体积瓶颈的,从来不是空格和换行,而是你在 _buttons.scss 里写了 5 层嵌套 + @extend %btn-base,又在 _cards.scss 里复刻了一遍。抽离 mixin 只是整理代码,不解决复用逻辑;压缩配置只是收尾动作,不修复源头冗余。关键判断就一条:构建后打开 main.css,搜 margin:,如果结果数远超你写的类数量,那就不是压缩没开好,是结构该动刀了。


















