有时候我们为了满足一些特定场景的需求,需要解析css代码,然后处理成特定的CSS,比如给所有的css选择器前面加上固定的类名等这些需求。那么如何才能解析css代码呢,需要用到一个包postcss
.
一、引用postcss
const postcss = require("postcss");
二、将 css 字符串转换为 AST
const AST = postcss.parse(styleStr)
由 css字符串 转换而来的 语法树 类似于浏览器中的DOM结构一样,每一层都会有一个 type 属性,最外层就像是根节点一样,type:'root'。
这一步,打印一下生成的AST结构如下:
-----------------------------------------------------
文件内容:
div {
background: red;
.a {
color: green;
}
}
.wrap .b {
font-size: 19px;
}
-----------------------------------------------------
postcss 解析 css:
Root {
raws: { semicolon: false, after: '' },
type: 'root',
nodes:
[
Rule {
raws: [Object],
type: 'rule',
nodes: [Array],
parent: [Circular],
source: [Object],
selector: 'div'
},
Rule {
raws: [Object],
type: 'rule',
nodes: [Array],
parent: [Circular],
source: [Object],
selector: '.wrap .b'
}
],
source:
{ input:
Input {
css: 'div {\n background: red;\n .a {\n color: green;\n }\n}\n.wrap .b {\n font-size: 19px;\n}',
hasBOM: false,
id: '<input css 1>' },
start: { line: 1, column: 1 }
}
}
-----------------------------------------------------
postcss 解析 css 返回对象的 nodes 属性:
[
Rule {
raws: { before: '', between: ' ', semicolon: false, after: '\n' },
type: 'rule',
nodes: [ [Object], [Object] ],
parent:
Root {
raws: [Object],
type: 'root',
nodes: [Circular],
source: [Object] },
source: { start: [Object], input: [Object], end: [Object] },
selector: 'div'
},
Rule {
raws: { before: '\n', between: ' ', semicolon: true, after: '\n' },
type: 'rule',
nodes: [ [Object] ],
parent:
Root {
raws: [Object],
type: 'root',
nodes: [Circular],
source: [Object] },
source: { start: [Object], input: [Object], end: [Object] },
selector: '.wrap .b'
}
]
-----------------------------------------------------
- AST.nodes 为一个对象数组,里面存放着 type: 'rule' 的对象,这些对象代表着每一条 css 规则。
- 以 Rule 代表一个rule对象,那么 Rule.type = ‘rule’,Rule.selector 即为此条规则的选择器字符串,Rule.nodes 又是一个对象数组,存放着 type: 'decl'的对象,这些对象代表着一条css规则中的每一条属性声明,例如 background: red;就是一条声明。
下面我们拿到AST对象可以进行一些操作:
const AST = postcss.parse(styleStr)
AST.nodes.forEach((item) => {
item.selector = `#${id} ${item.selector}`
})
三、将 AST 转换为相应的字符串
处理完AST数据后,我们可以把它转换成我们最终想要的css格式字符串,使用下面的方法:
postcss.stringify(AST, callback)
注意:这里有一个坑!
stringify 中的那个回调函数其实是多次调用的,就像forEach那样,所以真正的用法应该是:
const newCss = ''
postcss.stringify(AST, function (str) {
newCss += str
})
这样最后得到的 newCss 才是完整的转换后的css字符串。
网友评论