[Tools] PostCSS custom plugin

自定义插件

在 PostCSS 官网,实际上已经介绍了如何去编写一个自定义插件:https://postcss.org/docs/writing-a-postcss-plugin

  1. 需要有一个模板
module.exports = (opts = {}) => {
  // Plugin creator to check options or prepare caches
  return {
    postcssPlugin: 'PLUGIN NAME'
    // Plugin listeners
  }
}
module.exports.postcss = true

接下来就可以在插件里面添加一组监听器,对应的能够设置的监听器如下:

  • Root: node of the top of the tree, which represent CSS file.
  • AtRule: statements begin with @ like @charset "UTF-8" or @media (screen) {}.
  • Rule: selector with declaration inside. For instance input, button {}.
  • Declaration: key-value pair like color: black;
  • Comment: stand-alone comment. Comments inside selectors, at-rule parameters and values are stored in node’s raws property.
  1. 具体示例

现在在我们的 src 中新建一个 my-plugin.js 的文件,代码如下:

module.exports = (opts = {}) => {
  // Plugin creator to check options or prepare caches
  return {
    postcssPlugin: "PLUGIN NAME",
    Declaration(decl){
        console.log(decl.prop, decl.value)
    }
  };
};
module.exports.postcss = true;

在上面的代码中,我们添加了 Declaration 的监听器,通过该监听器能够拿到 CSS 文件中所有的声明。

接下来我们就可以对其进行相应的操作。

现在我们来做一个具体的示例:编写一个插件,该插件能够将 CSS 代码中所有的颜色统一转为十六进制。

这里我们需要使用到一个依赖包:color 该依赖就是专门做颜色处理的

pnpm add color -D

之后通过该依赖所提供的 hex 方法来进行颜色值的修改,具体代码如下:

const Color = require("color");

module.exports = (opts = {}) => {
  // Plugin creator to check options or prepare caches
  return {
    postcssPlugin: "convertColorsToHex",
    Declaration(decl) {
      // 先创建一个正则表达式,提取出如下的声明
      // 因为如下的声明对应的值一般都是颜色值
      const colorRegex = /(^color)|(^background(-color)?)/;
      if (colorRegex.test(decl.prop)) {
        try {
          // 将颜色值转为 Color 对象,因为这个 Color 对象对应了一系列的方法
          // 方便我们进行转换
          const color = Color(decl.value);
          // 将颜色值转换为十六进制
          const hex = color.hex();
          // 更新属性值
          decl.value = hex;
        } catch (err) {
          console.error(
            `[convertColorsToHex] Error processing ${decl.prop}: ${error.message}`
          );
        }
      }
    },
  };
};
module.exports.postcss = true;

Running the demo:

const fs = require("fs"); // 负责处理和文件读取相关的事情
const postcss = require("postcss");

// 引入我们自定义的插件
const myPlugin = require("./my-plugin.js");

const style = fs.readFileSync("src/index.css", "utf8");

postcss([myPlugin])
  .process(style, { from: undefined })
  .then((res) => {
    console.log(res.css);
  });
posted @ 2025-03-17 14:23  Zhentiw  阅读(24)  评论(0)    收藏  举报