一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

PostCSS 是個什么鬼東西?

 90食代美食 2016-06-01

  最近大漠前輩在群里發(fā)關于PostCSS的系列文章,但是耗子姐姐又說看了有點云里霧里的感覺,所以這篇文章將按一個思考的角度來理解一下 PostCSS 到底是一個什么東西。

  

  一、提出不懂的地方

  很多時候第一次在網(wǎng)上查詢 PostCSS 概念的時候,大家都解釋成一個后處理器的概念,其實個人覺得這些概念不重要,更為重要的有以下幾點:

  它本質上是一個什么東西?

  它能解決我們什么問題?

  它是通過什么方式來解決我們的問題?

  它解決我們的問題是為什么?

  怎么實現(xiàn)與 SASS、LESS、Stylus 相同的功能(因為它們被經常拿來比較)

  它由哪些東西組成?

  既然是程序可以用的,那么它的API呢?

  Q: 這個時候,你應該會問:為什么要將組成和API放到最后呢?

  A: 那是因為我們在認識一個不太清楚的東西的時候,第一次肯定是一個直觀的認識:它到底有什么用?而不會說,一來就去深入的研究它。不過這里本質還是要先說一下的,先留個印象。

  二、個個擊破

  1. 它本質上是一個什么東西?

  PostCSS 可以直觀的理解為:它就是一個平臺、平臺、平臺,重要的事情來三遍比較爽,哈哈!

  為什么說它是一個平臺呢?因為我們直接用它,感覺不能干什么事情,但是如果讓一些插件在它上面跑,那么將會很強大。

  PostCSS 提供了一個解析器,它能夠將 CSS 解析成抽象語法樹(AST)。

  上面兩條看完后,我們可以理解為下面這個模型。

  

  所以說,PostCSS 它需要一個插件系統(tǒng)才能夠發(fā)揮作用。我們可以通過“插件”來傳遞AST,然后再把AST轉換成一個串,最后再輸出到目標文件中去。當然,這里是有API可以用,這里先不講,免得暈了。

  2. 它能解決我們什么問題?它是通過什么方式來解決我們的問題?

  上面的圖很清晰,但是我還是不知道是個什么東西!所以接下來溫和點,直接從代碼層面來感官的認識一下。

  它能夠為 CSS 提供額外的功能;

  通過在 PostCSS 這個平臺上,我們能夠開發(fā)一些插件,來處理我們的CSS,比如熱門的:autoprefixer

  我們能夠使用JavaScript來開發(fā)插件(這點對前端來說很重要)

  好吧,看到一個熟悉的單詞了:autoprefixer,這里我們就讓它來當栗子吧,可能更容易理解一點。

  首先,我們需要做一些準備,安裝好需要的東西。

  // postcss 的命令行工具

  sudo npm install -g postcss-cli

  // autoprefixer 插件

  sudo npm install -g autoprefixer

  第一次用命令行能讓你更直觀去理解它哈,所以請要有一顆折騰的心。

  // 1. 先看下這個命令有哪些參數(shù)可以用

  postcss --help

  Usage: /usr/local/bin/postcss -use plugin [--config|-c config.json] [--output|-o

  output.css] [input.css]

  選項:

  -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ù)配置到配置文件中去。

  

  // config.json: 所有的配置

  // p.json: 僅有 autoprefixer 插件的配置

  // config.json 的內容

  {

  "use": ["autoprefixer"],

  "input": "src/index.css",

  "output": "index.css",

  "autoprefixer": {

  "browsers": "> 5%"

  }

  }

  // p.json 的內容

  {

  "autoprefixer": {

  "browsers": "> 5%"

  }

  }

  接下來我們在終端里面輸入:

  // 最簡潔的方式

  postcss -c config.json

  // 稍微復雜一點的方式,這里要用 -i 參數(shù),help里面沒有,我是從config.json里面的配置猜出來的,官方的那個寫法出不來

  postcss -u autoprefixer -c p.json -i src/index.css -o index.css

  // 最復雜的方式

  // 還是不寫比較好。。。

  跟平時想到的效果一樣:

  // src/index.css 中的源碼

  `* {

  transition: all .1s;

  }`

  // 轉換過后的代碼 index.css

  `* {

  -webkit-transition: all .1s;

  transition: all .1s;

  }`

  好吧,現(xiàn)在肯定就對 PostCSS 有一個感官的認識了,接下來就是需要自己動手去用一下 cssnext 這個插件了~看會發(fā)生什么,這里就不寫了,也挺好用的,不過應該還是草案狀態(tài)。

  我們開發(fā)不可能用命令行吧,所以這里再接著介紹代碼編寫,然后用 node 去執(zhí)行文件的方式。直接上代碼吧。

  // 1. 先安裝一下需要的庫

  npm install postcss --save-dev

  npm install autoprefixer --save-dev

  // 2. 其實應該先看看 postcss 的 package.json 文件,來看看包含了些什么,留個印象

  // 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) {

  // 這一行是學習的時候需要的,看一下到底對象里面包含什么

  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

  好吧,最后的結果和之前用命令行的方式一樣,只不過過程不同。這樣下來應該對 PostCSS 有了更多的感覺了吧。還沒完,不用慌~我們還需要提出一個問題,我都有 SASS 等預處理器了,還拿它來不是又給前端屆添亂么?因為這2年東西確實太多了~

  記住一句話:存在即合理

  既然合理,那么我們就看看它有什么優(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 我們只需要按標準的 CSS 來寫就行了,因為最后 autoprefixer 會幫我們做添加這個事情~

  box-shadow: 0 0 3px 5px rgba(222, 222, 222, .3);

  所以,這里就出現(xiàn)了一個經常大家說的未來編碼的問題。實際上,PostCSS 改變的是一種開發(fā)模式。

  SASS等工具:源代碼 -> 生產環(huán)境 CSS

  PostCSS:源代碼 -> 標準 CSS -> 生產環(huán)境 CSS

  這樣能體會出優(yōu)勢吧,但是目前大家都是 SASS + PostCSS 這樣的開發(fā)模式,其實我認為是不錯的,取長補短嘛,當然,在 PostCSS 平臺上都是可以做到的,只是目前這個過渡期,這樣更好,更工程化。接下來我就介紹一些方法來純粹是用 PostCSS。

  4. 怎么實現(xiàn)與 SASS、LESS、Stylus 相同的功能

  其實這一節(jié)我都不需要寫了~列一下插件就行了,因為插件才是實現(xiàn),PostCSS 只是提供了一個平臺。

  其實可以去官方看看:插件系統(tǒng)

  這里列幾個便于理解的插件

  postcss-each

  postcss-for

  postcss-mixins

  postcss-extend

  從名字就能看出來了吧~應該很好理解。

  5. 它由哪些東西組成?

  其實從官方介紹來看,只包含以下內容:

  CSS Parser

  CSS 節(jié)點樹 API

  source map 生成器

  生成節(jié)點樹串

  英文不太好 == ,就這 4 部分吧,從第一個圖其實也能夠看出來。

  其中的 I/O 體現(xiàn)在什么地方呢?好吧,很容易想到,主要體現(xiàn)在:

  Input: 插件程式和CSS Parser

  Output: 生成節(jié)點樹串

  CSS Parser 可以理解為一個內部過程,而插件程式主要體現(xiàn)在:

  postcss([ autoprefixer ])

  最后生成的節(jié)點樹串體現(xiàn)在:

  postcss().process().then(function (result) {

  // 就是這里了

  console.log(result.css);

  });

  // 現(xiàn)在我貼一下上面 result 對象的一個輸出結果

  // 這里我多引入了一個 cssnano 插件

  // 改變的代碼就這點,為了更全的看 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é)點樹串

  // 這里有自動補全和高效壓縮的效果

  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; }' } },

  // 這里應該是鏈式要用的吧,暫時不深究

  lastPlugin: {

  [Function]

  postcssPlugin: 'cssnano-reset-stylecache',

  postcssVersion: '5.0.10'

  }

  }

  其實吧,這樣有點抽象的,還是來看熟悉的 API 吧。

  這里出現(xiàn)了 sourcemap,說明 PostCSS 中的轉換功能是它必備的,但是必備并不等于:源代碼與目標代碼不能完全一致。

  這里吐槽一下 Chrome 的 sourcemap 功能,一坨屎!下面看看 firefox 里面的效果吧。

  

  這里 firefox 里面就自動映射了源文件,非常不錯!

  6. 既然是程序可以用的,那么它的API呢?

  其實官方有 API 的詳細解釋,我看了一下,一看就明白了,就不再花時間介紹了,大家可以去看看,這樣會知道,原來如此~

  PS: 大家可以先看看 Node Common 和 Node相關的,然后再看 plugin

  官方API

  這里看一個 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ā)插件可以看一下 官方插件指南

  更細致的地方,之后有時間的時候再寫寫 ^_^ 一說技術就停不下來了~

  大家在問?我怎么在工程上應用它呢?好吧,使用 gulp, grunt, webpack 都是可以的,我覺得都理解了 PostCSS ,使用這些就很簡單了,一查資料,拷貝一份配置就可以開始用了~就這樣吧,下次再結合 react 來介紹一下一個叫: postcss-js 的插件,看上去還不錯,還沒深入用,用到的時候再分享吧。

  •   其實我也是初學者,只是用了自己的學習方法來梳理成文章,下面都是我看過的文章,部分是引用的。這里就不全部舉例了,看的文章有點多。。。


    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    东京热加勒比一区二区三区 | 欧美胖熟妇一区二区三区| 欧美一区二区三区99| 99久久国产综合精品二区| 91精品日本在线视频| 欧美一区二区在线日韩| 欧美大胆美女a级视频| 欧美日韩有码一二三区| 国产内射一级一片内射高清视频| 九九热这里有精品20| 久久国产精品热爱视频| 字幕日本欧美一区二区| 麻豆一区二区三区在线免费| 国产精品国三级国产专不卡| 日韩人妻精品免费一区二区三区| 欧美一区二区三区五月婷婷| 国产精品免费不卡视频| 中字幕一区二区三区久久蜜桃| 成人午夜激情在线免费观看 | 国产免费操美女逼视频| 国产香蕉国产精品偷在线观看| 沐浴偷拍一区二区视频| 年轻女房东2中文字幕| 熟女中文字幕一区二区三区| 91欧美亚洲精品在线观看| 国产传媒中文字幕东京热| 国产又粗又猛又长又大| 又大又长又粗又黄国产| 五月婷日韩中文字幕四虎| 免费午夜福利不卡片在线 视频| 国产日韩熟女中文字幕| 亚洲熟妇av一区二区三区色堂 | 国产熟女一区二区三区四区| 色婷婷视频国产一区视频| 亚洲欧美视频欧美视频| 欧美一区日韩一区日韩一区| 国产女优视频一区二区| 亚洲av日韩av高潮无打码| 欧美乱码精品一区二区三| 亚洲日本久久国产精品久久| 国产又色又爽又黄的精品视频|