轻松上手开发一个 PostCSS(v8) 插件

635 阅读2分钟

PostCSS 是利用 JS 对CSS 代码进行转换处理。借助各种 PostCSS 插件可以用来为CSS 属性进行增删改查等操作(如: 添加浏览器兼容前缀、px转rem...), PostCSS 底层已经将 CSS 转义成 AST, 而我们开发一个 PostCSS 插件其实就是通过 JS 操作这个 AST 即可

  • 开发前注意事项:
    • PostCSS 8 插件不兼容 PostCSS 7 版本
    • PostCSS 会将 CSS 转为 AST, 我们只需要使用它提供的钩子去操作 AST

初始化一个插件项目

官方已经提供了脚本模板生成插件项目

npx postcss-plugin-boilerplate --npm postcss-wywppkd4test # tip: 点击tab切换命令输入内容

# 目录结构
.
├── CHANGELOG.md
├── LICENSE
├── README.md
├── index.js # 插件入口文件
├── index.test.js
├── package-lock.json
└── package.json

编写插件

postcss.plugin 提供了一些钩子事件, 方便处理CSS属性

  • 事件(钩子): postcss.org/api/#plugin
    • Root: CSS 语法树, 代表 css 文件
    • AtRule: 以@开头的内容(如: @media(screen){})
    • Rule: 已声明的选择器(如: input, button{})
    • Declaration: 属性名-属性值(如: color: red)
    • Comment: 注释
// index.js

/**
 * @type {import('postcss').PluginCreator}
 * opts 参数是插件的配置项
 * 该函数的返回值最终会被 postcss.plugin() 注册为一个插件
 */
module.exports = (opts = {}) => {

  return {
    // 插件名
    postcssPlugin: "postcss-plugin-wywppkd4test",

    /**
     * 这个钩子遍历所有大部分CSS属性(如background, color, font-size, etc.)
     * 其他特殊属性如 `@`开头的属性需要用 AtRule 钩子处理
     * @returns 
     */
    Declaration(decl, postcss) {
      // 避免插件重复执行
      if(decl.value.indexOf("rem") > -1) return

      // 将px单位替换为rem
      if(decl.value && decl.value.indexOf("px") > -1){
          const newVal = decl.value.replace(/px/g, "rem")
          decl.value = newVal
      }
    },

    /*
    Declaration: {
      // 查询更快: 如果你知道确切要改的属性名, 可以直接用属性名作为方法名, 这样查询效率更高
      color: (decl, postcss) {
        // 只处理 color 属性
      }
    }
    */
  };
};

module.exports.postcss = true;

发布 npm

略...

相关资料