Starxder 2019-06-30
前端工程化日益成熟今天,我们对于工具越来越深的封装。不管是从vue-cli的3.0版本起,还是umi、bigfish 等前端脚手架,对于webpack都封装在内,对于工程化无疑是高效的,但也在一定程度上让新手们者失去了从零配置一个项目的机会,所以很多时候还是希望能透过大神们的框架,研究一下底层结构。
PostCSS是一个通过JS插件转换样式表的工具,它本身并不是一门新的CSS语言,而是一个平台或者是生态心态,提供插件扩展服务即JS API,开发者可以根据这些接口,定制开发插件,目前比较流行的插件工具如:Autoprefixer 、Stylelint 、CSSnano。

大致步骤:
在PostCSS中有几个关键的处理机制:
Source string → Tokenizer → Parser → AST → Processor → Stringifier
将源css字符串进行分词
举个例子:
.className { color: #FFF; }通过Tokenizer后结果如下:
[
    ["word", ".className", 1, 1, 1, 10]
    ["space", " "]
    ["{", "{", 1, 12]
    ["space", " "]
    ["word", "color", 1, 14, 1, 18]
    [":", ":", 1, 19]
    ["space", " "]
    ["word", "#FFF" , 1, 21, 1, 23]
    [";", ";", 1, 24]
    ["space", " "]
    ["}", "}", 1, 26]
]以word类型为例,参数如下:
const token = [
     // token 的类型,如word、space、comment
    'word',
    // 匹配到的词名称
    '.className',
    // 代表该词开始位置的row以及column,但像 type为`space`的属性没有该值
    1, 1,
    // 代表该词结束位置的row以及column,
    1, 10
]经过Tokenizer之后,需要Parser将结果初始化为AST
this.root = {
    type: 'root',
    source: { input: {css: ".className { color: #FFF; }", hasBOM: false, id: "<input css 1>"},
                   start: { line: 1, column: 1 } ,
                  end: { line: 1, column: 27 }
    },
   raws:{after: "", semicolon: false}
   nodes // 子元素
}经过AST之后,PostCSS提供了大量JS API给插件用
插件处理后,比如加浏览器前缀,会被重新Stringifier.stringify为一般CSS。
PostCSS更多的是提供平台能力,赋能js的处理。