根本原因不是Sass压缩问题,而是@import全量引入和@extend滥用导致编译前体积爆炸;--style=compressed仅删空格注释,不合并选择器、不删未用规则,真正减体需按需导入+禁用@extend+PurgeCSS配合。

根本原因不是 Sass 编译器没压缩,而是你 @import "bootstrap/scss/bootstrap.scss" 这一行,把整套组件、工具类、打印样式、所有断点下的 utility 规则全塞进来了——哪怕只用了 .btn 和 .container。
为什么 sass --style=compressed 压根不减体积
sass --style=compressed 只做三件事:删空格、删换行、删注释。它不会合并重复选择器(比如 .modal .btn 和 .sidebar .btn),不会删掉未用的 .carousel 规则,也不会把 #ff0000 简写成 #f00 或简化 calc() 表达式。实测 gzip 后体积下降通常不到 3%。
真正让体积翻倍的是源码结构,不是输出格式。
- 运行
grep -o "\.btn" main.css | wc -l,如果结果超过 200,大概率是@extend或深层嵌套在作祟 - 运行
grep -o "margin:" main.css | wc -l,如果接近 1000,说明_spacing.scss全量生成了所有m-*/p-*类 - Webpack/Vite 默认不把 Sass 输出送进 PostCSS,
cssnano根本没机会工作
哪些 Sass 写法会让 CSS 体积“爆炸”
体积膨胀永远发生在编译前,而不是编译命令上。问题不在你用什么参数跑 sass,而在你写了什么 @import 和 @extend。
-
@extend %button-base被多个父级上下文调用,会复制出.header .btn、.modal .btn、.sidebar .btn等一堆带前缀的选择器 - 嵌套超过 4 层,例如
.card { .list { .item { &:hover { ... } } } },每层都展开父选择器,规则数呈指数增长 -
@import "bootstrap/scss/bootstrap.scss"全量引入——哪怕你只调用了px2rem()函数,tooltip、carousel、print的全部 CSS 都照打不误 - 循环生成工具类:
@for $i from 1 through 100 { .m-#{$i} { margin: #{$i}px; } }直接产出 100 条独立规则
如何真正控制编译前体积
必须放弃官方入口文件,手动构造最小依赖链。Bootstrap 的模块是解耦的,functions、variables、mixins 是基础,其余组件可按需拼接。
- 新建
src/custom-bootstrap.scss,只@import明确需要的部分,例如:@import "bootstrap/scss/functions"→@import "bootstrap/scss/variables"→@import "bootstrap/scss/mixins"→@import "bootstrap/scss/grid"→@import "bootstrap/scss/buttons" - 禁用
print.scss:它默认被bootstrap.scss引入,含大量媒体查询,不做 PDF 导出就直接跳过 - 精简
utilities:不要@import "bootstrap/scss/utilities",改用子文件,如只加_spacing和_text;再覆盖$grid-breakpoints,删掉不用的断点(多数项目只需xs和md) - 别信
$enable-tooltip: false这类变量——它只关 JS 初始化,.tooltip的 CSS 依然在,除非你删掉对应的@import行
PurgeCSS 不是万能药,但用对地方很关键
PurgeCSS 对 bootstrap.min.css 基本无效,因为它是黑盒压缩包,且 Bootstrap 5+ 大量依赖 data-bs-toggle 等属性触发样式,静态扫描根本抓不到。
它唯一有效的位置,是你自己用 Sass 编译出的 CSS 文件。
- 确保
content字段覆盖所有模板路径,例如:content: ["src/**/*.{vue,js,tsx}"];漏一个文件,里面动态用到的类就保留在最终 CSS 里 - PurgeCSS 必须放在 Sass 编译之后、CSS 压缩之前;顺序错,
cssnano就可能把已剔除的空规则当异常处理 - JS 动态插入的 class(如
element.classList.add('d-none'))不会被自动识别,得手动加进whitelist
最常被忽略的点:禁用 @extend。它在 Sass 层面就决定了选择器爆炸式增长,PurgeCSS 再强也救不了编译前就写死的冗余规则。










