css解析工具---postcss

2023-01-12  本文已影响0人  团猫咪爱吃玉米

有时候我们为了满足一些特定场景的需求,需要解析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' 
   }
 ]
-----------------------------------------------------

  1. AST.nodes 为一个对象数组,里面存放着 type: 'rule' 的对象,这些对象代表着每一条 css 规则。
  2. 以 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字符串。

上一篇 下一篇

猜你喜欢

热点阅读