锋利的 CSS 手术 🔪: postcss

495 阅读1分钟

postcss 的用很广,我们使用的 Vue, React 等等大多会使用 postcss 及其插件的能力。下面我们就来探究这把手术🔪:

安装

yarn add postcss

我们在 nodejs 环境中使用 postcss 的 api,探究 postcss 提供给了我们哪些能力?

简单的例子

import autoprefixer from "autoprefixer";
import postcss from "postcss";
import precss from "precss";
import fs from "fs";
import path from "path";

// 外部插件
import postcssPresetEnv from "postcss-preset-env";
import testPlugin from "./plugins/test-plugin";

console.log(postcss.list.space("1px calc(10% + 1px)"));
// [ '1px', 'calc(10% + 1px)' ]

console.dir(postcss.list.comma("black, linear-gradient(white, black)"));
// [ 'black', 'linear-gradient(white, black)' ]

const css = fs.readFileSync(path.join(__dirname, "../main.css"), {
  encoding: "utf-8"
});

// postcss 的调用得到 processor 对象
const processor = postcss([
  postcssPresetEnv(),
  autoprefixer,
  precss,
  testPlugin
]);

processor
  .process(css, { from: "./main.css", to: "./css/main.css" })
  .then(result => {
    fs.writeFileSync(path.join(__dirname, "../css/main.css"), result.css);
    console.log(result.css);
  });

postcss 源码

function postcss (...plugins) {
  if (plugins.length === 1 && Array.isArray(plugins[0])) {
    plugins = plugins[0]
  }
  return new Processor(plugins)
}

在 postcss 挂载了很多的方法:

  • plugin, 定义一个 postcss 插件
  • stringify 字符串化
  • parse 解析 css
  • vendor 厂商前缀
  • list 转换成数组
  • comment 评论实例
  • atRule 属性节点
  • decl 声明
  • rule 规则
  • root 根

定义一个插件

import postcss from "postcss";

export default postcss.plugin("test-plugin", () => {
  return (...args) => {
    console.log(`[plugin- test =>>>>>>>>]`, args);
  };
});

postcss.stringify

这个函数实例化了 Stringifier,然而 Stringifier 类上有需要实例方法,可以供我们使用。

postcss.parse

依赖两个类

  • Input (参数)
  • Parser (返回值实例)

postcss.vendor

vendor 对象上有两个方法:

  • prefix
  • unprefixed

postcss.list

  • split 方法
  • space 方法
  • comma 方法

postcss.atRule

atRule 继承自 Container, Container 继承自 Node

我们看到 atRule 继承自 Node, 提供了

  • append
  • prepend

两种操作

postcss.decl

Declaration 继承自 Node。首先是定义类型: type = 'decl'

postcss.rule

继承自 Container, 而 Container 继承自 Node。标记类型 this.type = 'rule'

postcss.root

继承自 Container, 而 Container 继承自 Node。标记类型 this.type = 'root'