点击在我的博客 xuxusheng.com 中查看,有更好的排版哦~
初学 postcss,随着不断的查阅相关的文档,对其的认识也在不断的加深,将一些不太熟悉的知识点在此记录下来,以供参考。
参考文档:
官方API:http://api.postcss.org/Root.html#walkRules
一篇译文:http://www.oschina.net/translate/its-time-for-everyone-to-learn-about-postcss?cmp
大漠前辈的系列文章:http://www.w3cplus.com/PostCSS/postcss-deep-dive-what-you-need-to-know.html
segmentfault上的一篇文章:https://segmentfault.com/a/1190000003909268
本文中css文件如下:
一、 将 css 字符串转换为 AST
之前不太熟悉 postcss 的语法,一直使用的 postcss([]).process( css ).then( function (result) {} )
的做法,最后那个 result 就是一个抽象语法树,太傻太傻。
查阅了API文档后,发现有一个 postcss.parse( )
方法,此方法可以直接将 css 字符串转换为 AST,用法如下:
var AST = postcss.parse( css )
同理,既然有 parse 方法,那么肯定会有一个 stringify 方法用于将 AST 转换为 css 字符串,但是这个stringify 的用法和 parse 有点区别,注意踩坑:
postcss.stringify(AST, function( css ) {
console.log( css )
})
注意注意!!,天坑!
stringify 中的那个回调函数其实是多次调用的,就像forEach那样,所以真正的用法应该是:
var newCss = ''
postcss.stringify(AST, function( str ) {
newCss += str
}
console.log(newCss)
这样最后得到的 newCss 才是完整的转换后的css字符串!!!!
二、 AST 结构
由 css字符串 转换而来的 语法树 类似于浏览器中的DOM结构一样,每一层都会有一个 type 属性,最外层就像是根节点一样,type:'root'
。
-
将整个语法树以变量 AST 存放,那么 AST.type = ‘root’,AST.nodes 为一个对象数组,里面存放着
type: 'rule'
的对象,这些对象代表着每一条 css 规则。 -
以 Rule 代表一个rule对象,那么 Rule.type = ‘rule’,Rule.selector 即为此条规则的选择器字符串,Rule.nodes 又是一个对象数组,存放着
type: 'decl'
的对象,这些对象代表着一条css规则中的每一条属性声明,例如width: 100px;
和height: 200px;
就是两条声明。 -
以 Decl 代表一个 decl 对象,那么 Decl.type = ‘decl’,Decl.prop 即为相应的属性名,如
'border
,Decl.value 即为相应的属性值,如1px solid red
三、stringify 中的坑
postcss.stringify(AST, callback)
方法可以将一个 AST 转换为相应的字符串,但是要注意的是,在转换的时候,AST.source 并没有起任何作用,就算删除此属性也不影响转换,主要是根据 AST.nodes中的元素来进行转换。
四、AST.first 中的坑
如果AST代表转换之后的语法树,那么 AST.first 即为第一个rule类型对象,AST.first.first 即为第一个rule类型对象的第一个decl类型对象。
注意:
此处有坑,如果想要修改 第一个 rule 类型对象,比如用 AST.nodes[0] = {}
是可以的,但是不能通过直接修改 AST.first 来改变。
这里好像是因为 AST.first 是 AST.nodes[0]的一个拷贝,每次访问AST.first的时候都会重新拷贝生成一次,不知道理解的对不对。