PostCSS 必须在 Sass 之后运行,因为 PostCSS 解析器只识别标准 CSS 语法,无法处理 $variable、@mixin 等 Sass 语法;@apply 和 @nest 是 PostCSS 阶段特性,Sass 完全不识别,且 loader 顺序错误会导致全部失效。

PostCSS 必须在 Sass 之后运行,顺序颠倒会导致 @apply、$variable、@nest 全部失效或报错——这不是配置技巧问题,而是编译链路的物理限制。
为什么 postcss-loader 不能放在 sass-loader 前面
PostCSS 解析器只认标准 CSS 语法。如果 postcss-loader 先执行,它会直接面对 $color-primary、@mixin、@use 这类 Sass 语法,立刻抛出 Unknown word 或 Unexpected token "$"。Sass 编译器(如 Dart Sass)才是唯一能消化这些语法的环节。
- Webpack 正确 loader 顺序:
style-loader→css-loader→postcss-loader→sass-loader - Vite 默认满足该顺序,但需检查
vite.config.ts中是否手动调整了css.preprocess或误加了postcss钩子提前介入 - 若用
sass --watchCLI 手动编译,必须确保输出的是.css文件,再喂给postcss-cli,不能把.scss直接丢进去
@nest 和 @apply 必须由 PostCSS 处理,Sass 根本不认识它们
@nest 是原生 CSS Nesting 草案语法,@apply 是 Tailwind 的 PostCSS 插件指令——二者在 Sass 编译阶段完全无效。Dart Sass 遇到它们,要么跳过整条声明,要么报 Unknown rule @apply。
-
postcss-nesting必须是 v10+,且在postcss.config.js插件数组中排首位;&必须紧贴@nest后,不能有空格:@nest &:hover { ... }✅,@nest & :hover❌ -
@apply只能在后缀为.css的文件里写,且该文件必须被 PostCSS 流程处理;写在.scss里等于注释 - 想在 Sass 里复用 Tailwind 值?别调
theme()(Sass 里根本不存在这个函数),改用$primary: #3b82f6+ 手动同步tailwind.config.js中的colors.primary
Sass 负责“写得清楚”,PostCSS 负责“发得靠谱”
Sass 的任务是把变量、嵌套、@mixin 编译成干净、语义明确的标准 CSS;PostCSS 的任务是在这基础上加前缀、压缩、嵌套转义、自定义属性降级——两者角色不可互换,也不可省略任一环。
立即学习“前端免费学习笔记(深入)”;
-
sass --style=compressed不等于真正最小化:它不简写0px→0、不合并重复规则、不删未用代码;必须接cssnano才算完整压缩链 - autoprefixer 只补前缀,它不会帮你定义
$spacing-lg,也不会生成响应式栅格类;这些仍是 Sass 的职责 - 所有 CSS 自定义属性(
--color-primary)必须由 Sass 输出(例如:root { --color-primary: #{$primary}; }),PostCSS 插件(如postcss-custom-properties)才可能对其做降级处理
最容易被忽略的一点:以为装了 postcss-sass 就能让 Sass 理解 @apply,其实它只是让 PostCSS 能解析 .scss 文件语法,并不改变编译顺序——@apply 依然不会被执行,只会被当作文本保留下来。


















