--style=compressed仅删空格换行注释、合并同选择器声明,不处理重复规则、未用选择器、数值颜色简写及逻辑冗余;真正减体积必须经sass→postcss→cssnano完整链路,源头优化嵌套、@extend和@import更关键。

开 --style=compressed 不等于压缩完成,它只是 Sass 层最基础的格式整理;真正减体积必须在 Sass 编译之后、最终输出之前接入 PostCSS + cssnano,否则 90% 的冗余规则(重复声明、未用选择器、未简写数值)根本不会被触碰。
为什么 sass --style=compressed 不能单独扛起压缩任务
它只做三件事:删空格换行、删注释、合并同一选择器下的相邻声明(如 margin-top: 10px; margin-right: 5px; → margin: 10px 5px 0 0;)。但它完全不处理:
- 同一份
display: flex; justify-content: center;在 20 个组件里被@include flex-center()展开 20 次,compressed会原样保留全部 20 份 -
0px不缩成0,#ff0000不缩成#f00,rgba(255, 0, 0, 0.5)里的空格也不删 - 源文件里
@if false { .unused { color: red; } }已被编译进输出,compressed照样打包 - 开启
sourceMap时,base64 字符串直接追加在 CSS 文件末尾,单文件多出 100KB+ 是常态
PostCSS + cssnano 必须接在 Sass 输出之后
Sass 不调用任何 PostCSS 插件,--load-path node_modules 或 --require cssnano 全无效。你得显式把两步串起来:
- Webpack 项目:确保
sass-loader输出后,CSS 再进postcss-loader,且css-minimizer-webpack-plugin配置中禁用内置压缩(它只压空格,不替代cssnano) - Vite 项目:默认对
.scss文件跳过 PostCSS;必须在vite.config.ts的css.postcss中显式启用,并确认build.cssCodeSplit开启以保障模块级处理 - 纯 CLI 流程:
sass src/main.scss dist/main.css --style=expanded --no-source-map && postcss dist/main.css -o dist/main.min.css --use autoprefixer cssnano—— 注意先用expanded,避免compressed态下cssnano解析失败
配置 cssnano 时容易踩的坑
它默认开启的优化项可能破坏现代 CSS 特性:
-
mergeLonghand会把margin: 0; margin-top: 1rem;合并成margin: 1rem 0 0;,但若你用了@layer或依赖特定层叠顺序,这会改写权重逻辑 -
normalizeWhitespace会删掉calc(100% - var(--gap))里的空格,变成calc(100%-var(--gap)),多数浏览器支持,但旧版 Safari 可能报错 - 伪类和属性选择器(如
:hover、[data-theme="dark"])常被postcss-discard-unused误删,需手动加ignore白名单 - 如果你的 HTML 是 JS 动态挂载的(比如 React/Vue 路由懒加载),
content配置的静态 HTML 路径根本覆盖不到所有类名,此时别硬上无用代码清理
真正卡住体积的从来不是空格和换行,而是 @extend 泛滥、@import 全量拼接、嵌套超过 4 层、循环生成工具类这些源码结构问题;压缩链再顺,也救不了源头失控的 SCSS。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











