[Tools] PostCSS custom plugin
自定义插件
在 PostCSS 官网,实际上已经介绍了如何去编写一个自定义插件:https://postcss.org/docs/writing-a-postcss-plugin
- 需要有一个模板
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 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 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);
});