从 Babel 到 PostCSS:重构你的 CSS 构建

一.PostCSS 是什么?为什么它值得深入了解?

PostCSS 是一个用 JavaScript 编写的 CSS 转换引擎。它的核心理念并不是像 Sass 或 Less 那样提供新语法,而是提供一个插件驱动的处理架构,你可以使用社区插件或自定义插件,对 CSS 做任何你想做的处理。

它做的事,类似于 Babel 之于 JavaScript。

Babel PostCSS
编译 JS 编译 CSS
插件系统 插件系统
支持 AST 转换 支持 AST 转换
Preset 支持 Preset 支持

换句话说,如果你能接受“现代 JavaScript 需要构建”,就应该理解“现代 CSS 同样需要构建”。


二.PostCSS 在现代前端中的定位

在一个 Vite 项目中,我们通常会使用如下 CSS 工具链:

  • Tailwind CSS: 原子化 CSS 框架
  • Autoprefixer: 自动添加前缀
  • postcss-preset-env: 支持未来 CSS 特性
  • CSS ModulesSCSS: 局部作用域

这些东西背后,其实都在使用 PostCSS 做统一处理。

架构示意图如下:

.css 文件
                ↓
       ┌────────────────────┐
       │     PostCSS 核心    │
       └────────────────────┘
        ↓       ↓        ↓
  autoprefixer  preset-env  tailwindcss
        ↓       ↓        ↓
          → 构建输出给浏览器

也就是说,PostCSS 是所有 CSS 逻辑的中间枢纽。


三.PostCSS 插件实战:从基础到高级

1.自动添加浏览器前缀(autoprefixer)

npm i autoprefixer postcss -D

postcss.config.js:

module.exports = {
  plugins: [require("autoprefixer")],
};

用途:写 display: flex 会自动加上 -webkit--ms- 前缀。


2.支持未来语法(postcss-preset-env)

npm i postcss-preset-env -D

配置:

module.exports = {
  plugins: [
    require("postcss-preset-env")({
      stage: 1, // 支持最新实验语法
      features: {
        "nesting-rules": true, // CSS 嵌套
      },
    }),
  ],
};

用途:让你在 CSS 中写未来版本的语法(比如嵌套、逻辑运算、容器查询)。


3.动态主题生成(自定义插件)

假设你希望自动将 CSS 中的主色 --primary 生成三种亮度变体。

你可以自己写一个插件:

const postcss = require("postcss");
module.exports = postcss.plugin("postcss-theme-generator", () => {
  return (root) => {
    root.walkDecls((decl) => {
      if (decl.prop === "--primary") {
        const baseColor = decl.value;
        decl.cloneAfter({ prop: "--primary-light", value: `${baseColor}99` });
        decl.cloneAfter({ prop: "--primary-dark", value: `${baseColor}cc` });
      }
    });
  };
});

四.PostCSS 与 Tailwind、UnoCSS 的关系

很多开发者以为 Tailwind 是一套独立的编译器,其实它最初就是个 PostCSS 插件。

  • Tailwind:高度依赖 PostCSS 插件机制来生成 class 和处理配置
  • UnoCSS:不依赖 PostCSS,本身是原子 CSS 编译器,但也提供 postcss-unocss 插件以供兼容

也就是说:

功能 Tailwind CSS UnoCSS
基于 PostCSS 吗? 不是
插件机制 PostCSS 插件 自定义解析器
运行方式 依赖构建工具 支持 CLI / Vite

五.你不知道的 PostCSS 冷知识

  1. PostCSS 的作者是 Andrey Sitnik,他也是 autoprefixer 和 Browserslist 的作者。
  2. PostCSS 支持完整的 CSS AST,可以用类似 Babel 的方式操作任意节点。
  3. 它不光能处理 CSS 文件,还能嵌入在 Markdown、HTML、Vue SFC、React 的 style 标签中。
  4. cssnano(压缩工具)、stylelint(CSS 检查工具)都可作为 PostCSS 插件运行。

六.常见误区 & 项目实战建议

“我不写 SCSS,就不需要 PostCSS”

即使你不用 Sass、不写 Nesting,仍然需要:

  • 自动前缀
  • CSS 压缩
  • 浏览器兼容处理
  • 变量替换(如 env 变量)
  • 主题暗黑模式处理

项目最佳实践(以 Vite 为例)

vite.config.ts 中:

export default defineConfig({
  css: {
    postcss: {
      plugins: [
        require("autoprefixer"),
        require("postcss-preset-env"),
        require("./postcss-theme-generator"),
      ],
    },
  },
});