読者です 読者をやめる 読者になる 読者になる

CSSのプリプロセスとポストプロセス、そしてReworkとPostCSS

この投稿はFrontrend Advent Calendar 2014の7日目の記事です。

CSSプリプロセッサーとポストプロセッサー、そしてそれらをビルドするツールであるReworkとPostCSSについて。

CSSプリプロセッサー、ポストプロセッサー

まずは用語の定義を確認する。CSSプリプロセッサー(またはメタ言語)とは、CSSとは異なる独自の構文で記述された文字列を入力とし、ブラウザが解釈可能なCSSコードを出力するもの。SassやLess、Stylus等がその実装に当たる。

f:id:morishitter:20141202002547p:plain

次にCSSポストプロセッサーとは、CSSを入力とし、より効果的なCSSに変換し、最適化するもの。例えば、コードを圧縮したり、自動でベンダープリフィックスを付与したり、プロパティ宣言の順番を読みやすいように並び変えたりするもので、CSSWringやAutoprefixer、CSSCombがその実装。いわゆるオプティマイザと呼ばれるものが行うことが、CSSにおけるポストプロセスだと思ってる。

f:id:morishitter:20141206205857p:plain

定義はだいたいこれで間違っていないはず。

Rework

ReworkCSSプリプロセッサーをビルドするためのツールTJ Holowaychuk製。開発者はReworkのプラグインを書くことで、独自のプリプロセスを定義することができる。MythはReworkで作られたプリプロセッサーだ。

あ!そうそう、僕もReworkを利用してYACP (Yet Another CSS Preprocessor)というものを作っている。YACPについては、CSS Architecture Advent Calendarの2日目として書いた記事があるので、よかったらこちらも読んでください。

Reworkは非常に小さいライブラリで、プラグインを呼び出してパースをする機能しか持たず、生成したASTをごにょごにょするAPIもない。そういえば、ReworkのRuby実装なんてものもあった。

PostCSS

PostCSSAndrey Sitnik氏が作っている、CSSポストプロセッサーをビルドするツール。Andrey氏はAutoprefixerの作者でもあり、AutoprefixerはPostCSSから作られている。

AutoprefixerはもともとReworkを使って作られていた。しかし、TJにAutoprefixerはCoffeeScriptだからダメだとかAPIがダサいとか言われたり、Reworkにブラウザハックをパースできないバグがあったりしたので、新しくPostCSSを作り、乗り換えた。

PostCSSとReworkは機能的によく似ている。PostCSSはReworkをよりリッチにしたもので、インデント幅やプロパティ宣言中のスペース等も考慮した完全なSource Mapに対応しており、ASTを操作するためのAPIも用意されている。

PostCSSのプラグインも徐々に充実してきている。そして、postcss-custom-propertiespostcss-nestedのようなプラグインが作られた。これらが提供するシンタックスは、ブラウザが解釈することができない独自構文だ。これらのプラグインを使ってPostCSSでビルドされたツールは、上述の定義に従うとポストプロセッサーとは呼べない。PostCSSはプリプロセッサーをビルドするツールでもあるのだ。

現に、プリプロセッサーであるMythをPostCSSで書きなおすという提案もあった。そして、cssnextというプリプロセッサー(CSS4 to CSS3のトランスパイラ)が作られた。これはMythと同機能のものだ。Reworkにできて、PostCSSにできないことはない。PostCSSはReworkの上位互換だと言える。

Reworkの開発はこの半年間停滞しているが、PostCSSは日々issueが立ち、議論され、バージョンが更新されている。ReworkのメンバーであるNicolas GallagherMaxime Thirouinも今はPostCSSにコミットしている。今後、この手のツールはPostCSSで作るのが主流となると予想できる。

PostCSSを褒めすぎたので一応欠点も述べておく。

まず、完全なSauce Mapに対応するためにPostCSSが提供しているAPIを使用しなければいけないが、これがなかなか複雑だということ。作者のAndrey氏自身扱いきれていない。MythがPostCSSで書きなおすのを拒んだのもこれが理由だ。僕もpostcss-namespaceを書いてみてこれを実感した。

あとは、個人的な問題だが「PostCSS」という名前。PostCSSでビルドするものはポストプロセッサーだけではなくなったので混乱する。

最後に

この記事では、CSSプリプロセッサーとポストプロセッサーについて定義を確認し、それぞれのビルドツールとして生まれたReworkとPostCSSについて述べた。少し(かなり?)マニアックな内容だったかもしれない。

ReworkやPostCSSのような、いわゆるプラグインアーキテクチャなメタCSSビルドツールの登場により、開発者は自分にとって必要な機能だけを持ったメタCSS言語を生成でき、必要があれば独自の機能を追加することができる。これらの影響を受けて、現在主流として使われているSassやStylusはどう変わっていく(変わっていけばいい)のか。これについても書こうと思ったけど、長くなってきたのでまた今度。

次回はyoheiMuneさんです。よろしくお願いします。