本文以我自己写的一个简单的插件:postCSS-px-to-vw 为例,介绍开发一个 PostCSS 插件的大致流程和原理。
PostCSS 介绍
PostCSS is a tool for transforming CSS with JS Plugins. These plugins can support variables and mixins, transpile future CSS syntax, inline images, and more
PostCSS 本身是一个功能比较单一的工具。它提供了一种方式用 JavaScript 代码来处理 CSS。它负责把 CSS 代码解析成抽象语法树结构(Abstract Syntax Tree,AST),再交由插件来进行处理。
开发插件的流程
PostCSS 的官方文档有较详细的教程,同时也提供 boilerPlate 和 guidelines,以及丰富的PostCSS API。
每个 PostCSS 插件都是一个 NodeJS 的模块。使用 postcss 的 plugin 方法来定义一个新的插件。插件需要一个名称,一般以“postcss-”作为前缀。插件还需要一个进行初始化的方法。该方法的参数是插件所支持的配置选项,而返回值则是另外一个方法,用来进行实际的处理。该处理方法会接受两个参数,css 代表的是表示 CSS AST 的对象,而 result 代表的是处理结果
- 在项目文件夹的node_modules中创建插件文件夹,一般以
postcss-
为前缀。 - 进入插件文件夹,
npm init
并且创建index.js
,我们的插件功能就在此实现。 - 安装postcss
npm install postcss --save
,你也可以安装你需要的其他依赖。 index.js
的基本代码如下:
|
|
CSS 与 AST
AST 抽象语法树
抽象语法树(Abstract Syntax Tree)也称为AST语法树,指的是源代码语法所对应的树状结构。也就是说,对于一种具体编程语言下的源代码,通过构建语法树的形式将源代码中的语句映射到树中的每一个节点上。
使用 AST Explorer 这个工具可以进行在线预览与编辑。
CSS 与 AST 的对应关系
例如以下的 CSS 代码,包含了注释、媒体查询、id 选择器和标签选择器。
|
|
表示成 AST 结构是这样的:
整棵树有一个根节点 root,上面有四个属性: raws、type、 nodes、 source。其中nodes
是树的节点数组,例如上面代码的 AST 的 nodes 数组是[comment, atrule, rule, rule]
每一个AST 上的节点都有其属性和方法,例如raws
、type
、name
、value
、prop
、sourse
等。
例如id 选择器
|
|
这一条 CSS rule 的 type 是 rule,其中有一条声明 border 属性的值,声明的type 为 decl,prop 是 border,value 是字符串1px solid black
使用 PostCSS 的 API 改变 CSS
PostCSS 自身只包括了 CSS 分析器,CSS 节点树 API,source map 生成器,CSS 节点拼接器,而基于PostCSS的插件都是使用了 CSS 节点树 API 来实现的。
下面介绍几种常用的 API:
css.walkRules()
方法用来遍历每一条 CSS 规则rule.walkDecls()
方法用来解析属性和值next()
方法返回当前节点的下一个节点,如果当前节点是最后一个子节点,则返回undefined
。(next() → {Node|undefined}
)
以postCSS-px-to-vw 为例:
|
|
PostCSS 为处理 CSS 提供了一种新的思路。通过 PostCSS 强大的插件体系,可以对 CSS 进行各种不同的转换和处理,本质上我们的插件都是通过 JavaScript 代码,使用 API,操作 AST,从而改变 CSS。