摘要:參考的文章最權(quán)威的初認(rèn)識一個(gè)不錯的東西理解等插件解析技術(shù)大漠的系列文章,應(yīng)用型很強(qiáng),推薦一個(gè)年齡差不多的開發(fā)者的解釋一篇稍微理論化解釋的文章一個(gè)開發(fā)模式簡單的優(yōu)劣比較大家也可以直接閱讀我的博客
前言
最近大漠前輩在群里發(fā)關(guān)于PostCSS的系列文章,但是耗子姐姐又說看了有點(diǎn)云里霧里的感覺,所以這篇文章將按一個(gè)思考的角度來理解一下 PostCSS 到底是一個(gè)什么東西。
一、提出不懂的地方很多時(shí)候第一次在網(wǎng)上查詢 PostCSS 概念的時(shí)候,大家都解釋成一個(gè)后處理器的概念,其實(shí)個(gè)人覺得這些概念不重要,更為重要的有以下幾點(diǎn):
它本質(zhì)上是一個(gè)什么東西?
它能解決我們什么問題?
它是通過什么方式來解決我們的問題?
它解決我們的問題是為什么?
怎么實(shí)現(xiàn)與 SASS、LESS、Stylus 相同的功能(因?yàn)樗鼈儽唤?jīng)常拿來比較)
它由哪些東西組成?
既然是程序可以用的,那么它的API呢?
Q: 這個(gè)時(shí)候,你應(yīng)該會問:為什么要將組成和API放到最后呢?
A: 那是因?yàn)槲覀冊谡J(rèn)識一個(gè)不太清楚的東西的時(shí)候,第一次肯定是一個(gè)直觀的認(rèn)識:它到底有什么用?而不會說,一來就去深入的研究它。不過這里本質(zhì)還是要先說一下的,先留個(gè)印象。
二、個(gè)個(gè)擊破 1. 它本質(zhì)上是一個(gè)什么東西?PostCSS 可以直觀的理解為:它就是一個(gè)平臺、平臺、平臺,重要的事情來三遍比較爽,哈哈!
為什么說它是一個(gè)平臺呢?因?yàn)槲覀冎苯佑盟?,感覺不能干什么事情,但是如果讓一些插件在它上面跑,那么將會很強(qiáng)大。
PostCSS 提供了一個(gè)解析器,它能夠?qū)?CSS 解析成抽象語法樹(AST)。
上面兩條看完后,我們可以理解為下面這個(gè)模型。
所以說,PostCSS 它需要一個(gè)插件系統(tǒng)才能夠發(fā)揮作用。我們可以通過“插件”來傳遞AST,然后再把AST轉(zhuǎn)換成一個(gè)串,最后再輸出到目標(biāo)文件中去。當(dāng)然,這里是有API可以用,這里先不講,免得暈了。
2. 它能解決我們什么問題?它是通過什么方式來解決我們的問題?上面的圖很清晰,但是我還是不知道是個(gè)什么東西!所以接下來溫和點(diǎn),直接從代碼層面來感官的認(rèn)識一下。
它能夠?yàn)?CSS 提供額外的功能;
通過在 PostCSS 這個(gè)平臺上,我們能夠開發(fā)一些插件,來處理我們的CSS,比如熱門的:autoprefixer
我們能夠使用JavaScript來開發(fā)插件(這點(diǎn)對前端來說很重要)
好吧,看到一個(gè)熟悉的單詞了:autoprefixer,這里我們就讓它來當(dāng)栗子吧,可能更容易理解一點(diǎn)。
首先,我們需要做一些準(zhǔn)備,安裝好需要的東西。
// postcss 的命令行工具 sudo npm install -g postcss-cli // autoprefixer 插件 sudo npm install -g autoprefixer
第一次用命令行能讓你更直觀去理解它哈,所以請要有一顆折騰的心。
// 1. 先看下這個(gè)命令有哪些參數(shù)可以用 postcss --help Usage: /usr/local/bin/postcss -use plugin [--config|-c config.json] [--output|-o output.css] [input.css] 選項(xiàng): -c, --config JSON file with plugin configuration -u, --use postcss plugin name (can be used multiple times) -o, --output Output file (stdout if not provided) -d, --dir Output directory -r, --replace Replace input file(s) with generated output [boolean] -s, --syntax Alternative input syntax parser -p, --parser Alternative CSS parser -t, --stringifier Alternative output stringifier -w, --watch auto-recompile when detecting source changes -v, --version 顯示版本號 [boolean] -h, --help 顯示幫助信息 [boolean] 示例: postcss --use autoprefixer -c Use autoprefixer as a postcss plugin options.json -o screen.css screen.css postcss --use autoprefixer Pass plugin parameters in --autoprefixer.browsers "> 5%" -o plugin.option notation screen.css screen.css postcss -u postcss-cachify -u Use multiple plugins and multiple autoprefixer -d build *.css input files Please specify at least one plugin name.
PS: 我貼出來是方便大家在看的時(shí)候不用電腦……^_^
好吧,先看一下文件目錄,這里我只說一下比較好寫的方式,就是將一些參數(shù)配置到配置文件中去。
// config.json: 所有的配置 // p.json: 僅有 autoprefixer 插件的配置 // config.json 的內(nèi)容 { "use": ["autoprefixer"], "input": "src/index.css", "output": "index.css", "autoprefixer": { "browsers": "> 5%" } } // p.json 的內(nèi)容 { "autoprefixer": { "browsers": "> 5%" } }
接下來我們在終端里面輸入:
// 最簡潔的方式 postcss -c config.json // 稍微復(fù)雜一點(diǎn)的方式,這里要用 -i 參數(shù),help里面沒有,我是從config.json里面的配置猜出來的,官方的那個(gè)寫法出不來 postcss -u autoprefixer -c p.json -i src/index.css -o index.css // 最復(fù)雜的方式 // 還是不寫比較好。。。
跟平時(shí)想到的效果一樣:
// src/index.css 中的源碼 `* { transition: all .1s; }` // 轉(zhuǎn)換過后的代碼 index.css `* { -webkit-transition: all .1s; transition: all .1s; }`
好吧,現(xiàn)在肯定就對 PostCSS 有一個(gè)感官的認(rèn)識了,接下來就是需要自己動手去用一下 cssnext 這個(gè)插件了~看會發(fā)生什么,這里就不寫了,也挺好用的,不過應(yīng)該還是草案狀態(tài)。
我們開發(fā)不可能用命令行吧,所以這里再接著介紹代碼編寫,然后用 node 去執(zhí)行文件的方式。直接上代碼吧。
// 1. 先安裝一下需要的庫 npm install postcss --save-dev npm install autoprefixer --save-dev // 2. 其實(shí)應(yīng)該先看看 postcss 的 package.json 文件,來看看包含了些什么,留個(gè)印象 // 3. p.js 中的代碼 var postcss = require("postcss"); var autoprefixer = require("autoprefixer"); var fs = require("fs"); var css = "* { transition: all .1s; }"; postcss([autoprefixer]) .process(css) .then(function(result) { // 這一行是學(xué)習(xí)的時(shí)候需要的,看一下到底對象里面包含什么 console.log(result); if (result.css) { fs.writeFileSync("index.css", result.css); } if (result.map) { fs.writeFileSync("index.css.map", result.map); } }); // 4. 執(zhí)行 p.js node p
好吧,最后的結(jié)果和之前用命令行的方式一樣,只不過過程不同。這樣下來應(yīng)該對 PostCSS 有了更多的感覺了吧。還沒完,不用慌~我們還需要提出一個(gè)問題,我都有 SASS 等預(yù)處理器了,還拿它來不是又給前端屆添亂么?因?yàn)檫@2年東西確實(shí)太多了~
記住一句話:存在即合理
既然合理,那么我們就看看它有什么優(yōu)勢唄~
3. 它解決我們的問題是為什么?優(yōu)勢何在?比如,我們用 SASS 來處理 box-shadow 的前綴,我們需要這樣寫:
/* CSS3 box-shadow */ @mixin box-shadow($top, $left, $blur, $size, $color, $inset: false) { @if $inset { -webkit-box-shadow: inset $top $left $blur $size $color; box-shadow: inset $top $left $blur $size $color; } @else { -webkit-box-shadow: $top $left $blur $size $color; box-shadow: $top $left $blur $size $color; } }
使用 PostCSS 我們只需要按標(biāo)準(zhǔn)的 CSS 來寫就行了,因?yàn)樽詈?autoprefixer 會幫我們做添加這個(gè)事情~
box-shadow: 0 0 3px 5px rgba(222, 222, 222, .3);
所以,這里就出現(xiàn)了一個(gè)經(jīng)常大家說的未來編碼的問題。實(shí)際上,PostCSS 改變的是一種開發(fā)模式。
SASS等工具:源代碼 -> 生產(chǎn)環(huán)境 CSS
PostCSS:源代碼 -> 標(biāo)準(zhǔn) CSS -> 生產(chǎn)環(huán)境 CSS
這樣能體會出優(yōu)勢吧,但是目前大家都是 SASS + PostCSS 這樣的開發(fā)模式,其實(shí)我認(rèn)為是不錯的,取長補(bǔ)短嘛,當(dāng)然,在 PostCSS 平臺上都是可以做到的,只是目前這個(gè)過渡期,這樣更好,更工程化。接下來我就介紹一些方法來純粹是用 PostCSS。
4. 怎么實(shí)現(xiàn)與 SASS、LESS、Stylus 相同的功能其實(shí)這一節(jié)我都不需要寫了~列一下插件就行了,因?yàn)椴寮攀菍?shí)現(xiàn),PostCSS 只是提供了一個(gè)平臺。
其實(shí)可以去官方看看:插件系統(tǒng)
這里列幾個(gè)便于理解的插件
postcss-each
postcss-for
postcss-mixins
postcss-extend
從名字就能看出來了吧~應(yīng)該很好理解。
5. 它由哪些東西組成?其實(shí)從官方介紹來看,只包含以下內(nèi)容:
CSS Parser
CSS 節(jié)點(diǎn)樹 API
source map 生成器
生成節(jié)點(diǎn)樹串
英文不太好 == ,就這 4 部分吧,從第一個(gè)圖其實(shí)也能夠看出來。
其中的 I/O 體現(xiàn)在什么地方呢?好吧,很容易想到,主要體現(xiàn)在:
Input: 插件程式和CSS Parser
Output: 生成節(jié)點(diǎn)樹串
CSS Parser 可以理解為一個(gè)內(nèi)部過程,而插件程式主要體現(xiàn)在:
postcss([ autoprefixer ])
最后生成的節(jié)點(diǎn)樹串體現(xiàn)在:
postcss().process().then(function (result) { // 就是這里了 console.log(result.css); }); // 現(xiàn)在我貼一下上面 result 對象的一個(gè)輸出結(jié)果 // 這里我多引入了一個(gè) cssnano 插件 // 改變的代碼就這點(diǎn),為了更全的看 result var opts = { from: "src/index.css", to: "index.css", // 配置 map map: { inline: false } }; postcss([ autoprefixer, cssnano() ]).process(css, opts) Result { processor: Processor { // 處理器的版本號 version: "5.0.10", // 加載的一堆插件 plugins: [ [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object] ] }, messages: [], root: Root { raws: { semicolon: false, after: "" }, type: "root", nodes: [ [Object] ], source: { input: [Object], start: [Object] }, _autoprefixerDisabled: false, _autoprefixerPrefix: false, rawCache: { colon: ":", indent: "", beforeDecl: "", beforeRule: "", beforeOpen: "", beforeClose: "", beforeComment: "", after: "", emptyBody: "", commentLeft: "", commentRight: "" } }, // 我們代碼中配置 opts 變量 opts: { from: "src/index.css", to: "index.css" }, // 這就是重新生成的 節(jié)點(diǎn)樹串 // 這里有自動補(bǔ)全和高效壓縮的效果 css: "*{-webkit-transition:all .1s;transition:all .1s}", // map的文件的配置 map: SourceMapGenerator { _file: "index.css", _sourceRoot: null, _skipValidation: false, _sources: ArraySet { _array: [Object], _set: [Object] }, _names: ArraySet { _array: [], _set: {} }, _mappings: MappingList { _array: [Object], _sorted: true, _last: [Object] }, _sourcesContents: { "$src/index.css": "* { transition: all .1s; }" } }, // 這里應(yīng)該是鏈?zhǔn)揭玫陌?,暫時(shí)不深究 lastPlugin: { [Function] postcssPlugin: "cssnano-reset-stylecache", postcssVersion: "5.0.10" } }
其實(shí)吧,這樣有點(diǎn)抽象的,還是來看熟悉的 API 吧。
這里出現(xiàn)了 sourcemap,說明 PostCSS 中的轉(zhuǎn)換功能是它必備的,但是必備并不等于:源代碼與目標(biāo)代碼不能完全一致。
這里吐槽一下 Chrome 的 sourcemap 功能,一坨屎!下面看看 firefox 里面的效果吧。
這里 firefox 里面就自動映射了源文件,非常不錯!
6. 既然是程序可以用的,那么它的API呢?其實(shí)官方有 API 的詳細(xì)解釋,我看了一下,一看就明白了,就不再花時(shí)間介紹了,大家可以去看看,這樣會知道,原來如此~
PS: 大家可以先看看 Node Common 和 Node相關(guān)的,然后再看 plugin
官方API
這里看一個(gè) DEMO,主要做 rem 和 px 單位之間的互換,加入 processors 就可以用了,很方便:
var custom = function(css, opts){ css.eachDecl(function(decl){ decl.value = decl.value.replace(/d+rem/, function(str){ return 16 * parseFloat(str) + "px"; }); }); };
開發(fā)插件可以看一下 官方插件指南
更細(xì)致的地方,之后有時(shí)間的時(shí)候再寫寫 ^_^ 一說技術(shù)就停不下來了~
大家在問?我怎么在工程上應(yīng)用它呢?好吧,使用 gulp, grunt, webpack 都是可以的,我覺得都理解了 PostCSS ,使用這些就很簡單了,一查資料,拷貝一份配置就可以開始用了~就這樣吧,下次再結(jié)合 react 來介紹一下一個(gè)叫: postcss-js 的插件,看上去還不錯,還沒深入用,用到的時(shí)候再分享吧。
其實(shí)我也是初學(xué)者,只是用了自己的學(xué)習(xí)方法來梳理成文章,下面都是我看過的文章,部分是引用的。這里就不全部舉例了,看的文章有點(diǎn)多。。。
參考的文章最權(quán)威的初認(rèn)識 https://github.com/postcss/postcss
一個(gè)不錯的東西 rework https://github.com/reworkcss
理解 AST 等插件解析技術(shù) http://rapheal.sinaapp.com/category/js/uglify%E6%BA%90%E7%A0%81/
大漠的系列文章,應(yīng)用型很強(qiáng),推薦 http://www.w3cplus.com/blog/tags/517.html
一個(gè)年齡差不多的開發(fā)者的解釋 http://acgtofe.com/posts/2015/05/modular-transforming-with-postcss/
一篇稍微理論化解釋的文章 http://www.oschina.net/translate/its-time-for-everyone-to-learn-about-postcss?cmp
一個(gè)開發(fā)模式簡單的優(yōu)劣比較 http://caibaojian.com/css-processor.html
大家也可以直接閱讀我的博客:http://www.60sky.com
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/111165.html
摘要:之前有研究過做過假設(shè),在插件列表中,的插件執(zhí)行順序自上而下,一切看起來似乎是沒有任何問題的。再有摘自深入設(shè)計(jì)摘自寫的姿勢這兩張圖則應(yīng)該是說明了我之前的假設(shè),插件中的執(zhí)行順序自上而下。先來看看一片來自的這段會不會跟這個(gè)有關(guān)呢,我先埋個(gè)伏筆。 圖解PostCSS的插件執(zhí)行順序 文章其實(shí)是一系列的早就寫完了. 才發(fā)現(xiàn)忘了發(fā)在SegmentFault上面, 最早發(fā)布于https://gitee...
摘要:而則可制定個(gè)人需求的一套解決方案僅安裝需要的插件。迫不及待的你已經(jīng)等不及安裝使用了吧。安裝及使用一般是結(jié)合自動化工具使用,如果要單獨(dú)使用可以安裝,這里我先對的安裝使用講解下。接下來說點(diǎn)實(shí)際的,如何利用結(jié)合自動化工作在項(xiàng)目中使用。 PostCSS介紹 PostCSS是一個(gè)利用JS插件來對CSS進(jìn)行轉(zhuǎn)換的工具,這些插件非常強(qiáng)大,強(qiáng)大到無所不能。其中,Autoprefixer就是眾多Post...
摘要:本期主要介紹以下幾個(gè)插件和幾個(gè)坑和坑這個(gè)就不用多說了,必裝插件之一??此茖懛]有任何問題。編譯后的結(jié)果那么這樣就沒有問題了。 PostCSS常用插件介紹 繼上一次PostCSS學(xué)習(xí)指南(一)后,漸漸開始在項(xiàng)目中應(yīng)用。 這次決定主要講解一些個(gè)人認(rèn)為非常有幫助的PostCSS插件。 本期主要介紹以下幾個(gè)插件和幾個(gè)坑 autoprefixer postcss-partial-import...
摘要:張鑫旭老師的文章寫的很棒,解決了我的許多困惑。所以,基礎(chǔ)知識的牢固就顯得尤為重要是個(gè)不怎么聽話的孩子,總是會搞出一些奇奇怪怪的事情來張鑫旭老師十年磨一劍,鉆研的魔法,可見其中技術(shù)細(xì)節(jié)有多復(fù)雜。 ??從實(shí)習(xí)算起,到現(xiàn)在工作了也有一年半的時(shí)間了,在這期間,深深感受到了前端領(lǐng)域的飛速發(fā)展,在這里記錄一下自己的成長歷程,算是對知識的一個(gè)梳理,也希望幫助到剛?cè)胄械耐瑢W(xué)們。說來慚愧,大學(xué)里并沒有涉...
摘要:張鑫旭老師的文章寫的很棒,解決了我的許多困惑。所以,基礎(chǔ)知識的牢固就顯得尤為重要是個(gè)不怎么聽話的孩子,總是會搞出一些奇奇怪怪的事情來張鑫旭老師十年磨一劍,鉆研的魔法,可見其中技術(shù)細(xì)節(jié)有多復(fù)雜。 ??從實(shí)習(xí)算起,到現(xiàn)在工作了也有一年半的時(shí)間了,在這期間,深深感受到了前端領(lǐng)域的飛速發(fā)展,在這里記錄一下自己的成長歷程,算是對知識的一個(gè)梳理,也希望幫助到剛?cè)胄械耐瑢W(xué)們。說來慚愧,大學(xué)里并沒有涉...
閱讀 1075·2023-04-26 02:02
閱讀 2416·2021-09-26 10:11
閱讀 3569·2019-08-30 13:10
閱讀 3758·2019-08-29 17:12
閱讀 731·2019-08-29 14:20
閱讀 2199·2019-08-28 18:19
閱讀 2245·2019-08-26 13:52
閱讀 969·2019-08-26 13:43