Sass 的 --style=compressed 仅删除空格、换行和注释,不合并选择器、不简化数值、不剔除未用代码;真正压缩需 PostCSS(如 cssnano)在 Sass 编译后介入,且源码结构冗余(如深层嵌套、滥用 @extend)才是体积膨胀主因。

Sass 本身没有“插件”能自动优化 CSS 压缩率——它不支持加载 cssnano 或 PostCSS 插件,所谓“Sass 插件压缩”是常见误解。真正起作用的是构建流程中后续环节的工具链,Sass 只负责语法转换和基础格式整理。
为什么 sass --style=compressed 不等于压缩优化
这个参数只做三件事:删空格、删换行、删注释。它不会:
- 合并重复选择器(比如多个
.btn规则) - 简化数值(
0px→0,#ff0000→#f00) - 剔除未使用的 CSS(哪怕源码里写了
@if false { .dead { color: red; } },也会编译进去) - 重写
calc()或处理 CSS 自定义属性
实测:一个深层嵌套的 @extend 生成的选择器爆炸,体积可能比 --style=compressed 多出 3–5 倍;而它对这种膨胀完全无感。
真正有效的压缩链必须分两步走
顺序不能错,否则 PostCSS 拿不到可解析的结构:
立即学习“前端免费学习笔记(深入)”;
- 第一步:
sass输出--style=expanded(非compressed)——保证嵌套、自定义属性、@layer等语法完整保留,便于 PostCSS 正确识别 - 第二步:
postcss接收该 CSS,用cssnano(含mergeLonghand、normalizeWhitespace、discardComments)做深度精简
命令示例:npx sass src/main.scss dist/main.css --style=expanded && npx postcss dist/main.css -o dist/main.min.css --use autoprefixer cssnano
Webpack 中 sass-loader 和 postcss-loader 必须显式桥接
很多人配了 css-minimizer-webpack-plugin 却没效果,问题出在 pipeline 断点:
-
sass-loader的sassOptions.outputStyle必须设为'compressed'—— 否则默认'nested'输出,光靠后续压缩也救不回体积 - 但
postcss-loader必须放在sass-loader之后、css-loader之前,否则cssnano根本收不到 Sass 编译后的 CSS 字符串 - 配置位置极易写错:要写在
module.rules.use[x].options.sassOptions下,不是顶层或loaderOptions外
最容易被忽略的体积源头:Sass 源码结构本身
所有压缩工具都只能处理“已经编译出来的 CSS”,它们无法修复源码级浪费:
-
@import全量引入大库(如 Bootstrap Sass),哪怕只调了一个函数,整个文件都进输出 - 嵌套超过 4 层(
.card { .list { .item { ... } } }),每层复制前缀,规则数指数增长 -
@for $i from 1 through 100生成工具类,直接产出 100 条规则 -
@extend %base在多个上下文使用,生成.header .btn、.modal .btn等爆炸式选择器
验证方法:grep -o "\.btn" dist/main.css | wc -l,数字异常高就说明源码里有结构性冗余——这时候调再强的压缩参数也没用。


















