PostCss
是一個(gè)CSS
后處理工具
PostCss
是什么
????首先,聊PostCss
之前喝滞,我們得知道什么是CSS
后處理工具红竭。我們比較熟悉的Less,Sass,Stylus
,這類工具都屬于CSS
預(yù)處理工具通過特殊的規(guī)則变隔、文本格式最終生成CSS
文件规伐。而PostCss
則是對(duì)CSS
進(jìn)行處理,最終生成CSS
匣缘。
????多數(shù)人最早接觸和使用的應(yīng)該是Autoprefixer
這款插件猖闪,Autoprefixer
的功能是:以 Can I Use 上的 瀏覽器支持?jǐn)?shù)據(jù) 為基礎(chǔ),自動(dòng)處理兼容性問題肌厨。
# Autoprefixer 處理前的CSS樣式
.container {
display: flex;
}
.item {
flex: 1;
}
# Autoprefixer 處理后的CSS樣式
.container {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
}
.item {
-webkit-box-flex: 1;
-webkit-flex: 1;
-ms-flex: 1;
flex: 1;
}
通過使用Autoprefixer
插件培慌,很大程度上節(jié)省了CSS
重復(fù)樣式的編寫。Autoprefixer
正是PostCss
眾多插件中的一款柑爸,查找更多插件吵护,點(diǎn)這里。
PostCss
處理Css
過程
作為一款可安裝使用各類插件的工具表鳍,PostCss
提供的API
還是很簡(jiǎn)潔明了的(吐槽一下Less,什么鬼玩意兒何址,API文檔都不寫的)
- 將
Css
文件信息處理成樹型結(jié)構(gòu)的Js
對(duì)象。 - 根據(jù)配置插件的順序?qū)湫徒Y(jié)構(gòu)的
Js
對(duì)象 進(jìn)行操作进胯。 - 最終將處理后獲得的樹型結(jié)構(gòu)的
Js
對(duì)象輸出為Css
文件用爪。
那么關(guān)鍵點(diǎn)就在與Css
被處理后生成的樹型結(jié)構(gòu)的Js
對(duì)象,那么先讓我們看一看它的小裙裙里藏著什么胁镐。
PostCss
處理Css
詳解
- 下圖為一個(gè)很標(biāo)準(zhǔn)的
Css
偎血,有注釋、帶有@
的媒體查詢盯漂、以及選擇器樣式颇玷。
- 上面的
Css
最終會(huì)處理為下圖結(jié)構(gòu),通過打印信息我們可以發(fā)現(xiàn)樹型結(jié)構(gòu)的Js
對(duì)象是一個(gè)名為Root
的構(gòu)造函數(shù)就缆,而起樹型結(jié)構(gòu)的nodes
節(jié)點(diǎn)下還有Commont
帖渠,AtRule
,Rule
構(gòu)造函數(shù)竭宰。
- 上面的
- 樹型結(jié)構(gòu)的
Js
對(duì)象在最后會(huì)處理成名為Result
的構(gòu)造函數(shù)空郊,如下圖份招,帶有css
這個(gè)屬性,包含完整的Css
信息狞甚,最終會(huì)被寫入到文件中锁摔。
PostCss
中的各種構(gòu)造函數(shù)
在上面部分關(guān)于 PostCss
處理Css
中,生成了很多構(gòu)造函數(shù)哼审。而 PostCss
的神奇功能也都圍繞著這些構(gòu)造函數(shù)谐腰,接下來我們一一介紹。
Root
:PostCss
處理過的Css
涩盾,整個(gè)處理過程基本上都在圍繞著Root
十气,Commont
,AtRule
春霍,Rule
都是它的子節(jié)點(diǎn)砸西。-
Commont
:Css
中的注釋信息,注釋的內(nèi)容在Commont.text
下终畅。
Commont -
AtRule
: 為帶@
標(biāo)識(shí)的部分籍胯,name
為標(biāo)識(shí)名稱,params
為標(biāo)識(shí)參數(shù)离福。nodes
為內(nèi)部包含的其他子節(jié)點(diǎn)杖狼,可以是Commont
,AtRule
妖爷,Rule
蝶涩,這讓我們可以自定義更多的規(guī)則,
AtRule -
Rule
: 選擇器樣式部分絮识,一個(gè)選擇器代表一個(gè)Rule
绿聘,選擇器對(duì)應(yīng)的樣式列表nodes
為Declaration
構(gòu)造函數(shù),
Rule -
Declaration
: 為Css
樣式屬性,prop
為樣式屬性次舌,value
為樣式值熄攘。可給Rule
手動(dòng)添加樣式屬性彼念,也可以修改prop
,value
挪圾。上文提到的Autoprefixer
就是通過clone
當(dāng)前屬性,修改prop
并添加到選擇器下逐沙。
Declaration Result
: 通過root.toResult()
方法可以獲取到帶有css
全文本信息的Result
對(duì)象哲思,也代表這我們PostCss
單個(gè)插件到了尾聲。接下來直接將result.css
寫入對(duì)應(yīng)的文件即可吩案。
如何使用 PostCss
插件
PostCss
插件有很多種使用方式棚赔,
- 可以配合在
postcss-loader
的options
配置各種插件
plugins: [
themePlugin({}),
autoprefixer({})
]
- 也可以直接在
Node
程序中使用
postcss([themePlugin({})])
.process(css, {from: ``, to: ``})
.then(result => {
// 根據(jù)配置文件themeList,分別處理對(duì)應(yīng)的文件,打包各css 文件
})
.catch(error => {
throw new Error(error)
})
如何編寫一個(gè) PostCss
插件
上文中,我們對(duì)Css
處理后生成的Root
以及其節(jié)點(diǎn)下的Commont
靠益,AtRule
丧肴,Rule
, Declaration
有了基本的認(rèn)識(shí)捆毫,那么我們是如何獲得Root
闪湾,又將拿這些構(gòu)造函數(shù)做些什么呢冲甘。
var postcss = require('postcss');
module.exports = postcss.plugin('postcss-test-plugin', function (opts) {
opts = opts || {}; // 處理 options
return function (root, result) {
//遍歷所有的選擇器
root.walkRules(function(rule) {
//遍歷所有的屬性
rule.walkDecls(function(decl) {
//dect 是一個(gè)包含屬性-值對(duì)和一些操作方法的樣式對(duì)象绩卤,最重要的兩個(gè)屬性是decl.prop 屬性名和decl.value 屬性值.
//過濾包含 overflow , overflow-x , overflow-y 的屬性
rule.walkDecls(/^overflow-?/, function(decl) {
if (decl.value === 'scroll') {
//判斷是否已經(jīng)有-webkit-overflow-scrolling,防止重復(fù)添加
var hasTouch = rule.some(function(i) {
return i.prop === '-webkit-overflow-scrolling';
});
if (!hasTouch) {
rule.append({
prop: '-webkit-overflow-scrolling',
value: 'touch'
});
}
}
});
});
});
};
});
通過上述插件代碼的示例江醇,其實(shí)已經(jīng)可以很清楚的知道編寫 PostCss
插件的思路濒憋。
- 重點(diǎn)對(duì)象是
Root
,Commont
陶夜,AtRule
凛驮,Rule
,Declaration
条辟,Result
; - 遍歷方法黔夭,
walkCommonts
,walkAtRules
羽嫡,walkRules
本姥,walkDels
; - 節(jié)點(diǎn)操作(上面的構(gòu)造函數(shù)基本上都有以下類似的操作),
append
杭棵,clone
婚惫,remove
,toString
魂爪。更多操作方法
通過整體梳理先舷,從PostCss
是什么,做什么滓侍。到PostCss
插件的使用蒋川,以及編寫,應(yīng)該對(duì)PostCss
有了整體的認(rèn)識(shí)撩笆。PostCss
的API
雖然沒有那么復(fù)雜捺球,但足夠我們做很多事情,讓前端工程化玩法更多浇衬。示例也只是一個(gè)簡(jiǎn)單的插件代碼懒构,還有很多像Autoprefixer
一樣優(yōu)秀的插件,我們甚至可以用PostCss
插件像eslint
一樣規(guī)范Css
編寫耘擂。
- 注意事項(xiàng):
-
postcss-loader
默認(rèn)使用.postcsssrc.js
文件的配置胆剧,postcss.config.js
和.postcsssrc.js
同時(shí)存在是會(huì)優(yōu)先使用.postcsssrc.js
中的配置 - 編寫
PostCss
插件時(shí),可能會(huì)有很多Node
文件操作,請(qǐng)注意同步異步操作的適用情況秩霍,避免使用不當(dāng)篙悯,導(dǎo)致產(chǎn)出的css
文件內(nèi)容錯(cuò)誤 -
vue-loader
處理.vue
文件時(shí),如果<style>
標(biāo)簽帶有scoped
铃绒,那么在經(jīng)過css-loader > postcss-loader > vue-loader
這一順序處理后鸽照,scoped
標(biāo)記會(huì)在postcss-loader
使用插件產(chǎn)出的css樣式運(yùn)轉(zhuǎn)到vue-loader
處理時(shí)在css
和html
標(biāo)簽處添加[data-v-hash碼]
,此時(shí)postcss-loader
引用的PostCss
插件如果有導(dǎo)出類的操作颠悬,可能會(huì)導(dǎo)致scoped
失效矮燎。并并且沒辦法在vue-loader
之后再使用postcss
這種思路。只能build
的時(shí)候在webpack
構(gòu)建鉤子赔癌,在處理完.vue
文件后再處理相關(guān)的導(dǎo)出操作诞外,此時(shí)是完整的。(此處還有很多細(xì)節(jié)灾票,具體有問題峡谊,可單獨(dú)私聊。) - 新版的
vue-loader
的api
和老版本的有挺大的差別刊苍,請(qǐng)做好甄別既们。
-
后續(xù)看情況更新
有用的網(wǎng)址