自定义插件
在 PostCSS 官网,实际上已经介绍了如何去编写一个自定义插件:https://postcss.org/docs/writing-a-postcss-plugin
- 需要有一个模板
module.exports = (opts = {}) => {// Plugin creator to check options or prepare cachesreturn {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 instanceinput, button {}
.Declaration
: key-value pair likecolor: black
;Comment
: stand-alone comment. Comments inside selectors, at-rule parameters and values are stored in node’sraws
property.
- 具体示例
现在在我们的 src 中新建一个 my-plugin.js 的文件,代码如下:
module.exports = (opts = {}) => {// Plugin creator to check options or prepare cachesreturn {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 cachesreturn {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);});