3日目では、PostCSSのASTを簡単に、効率よく操作するためのAPIをいくつか紹介しました。今日は、実際にPostCSSのプラグインを作り切るところまで説明します。
作るプラグイン
今回は、PostCSSのプラグインの例として、overflow-wrap プロパティが使われたとき、フォールバックとして word-wrap プロパティを追加するためのプラグインを考えます。
a {
overflow-wrap: break-word;
}
上記のようなCSSを、下記のように変換します。
a {
word-wrap: break-word;
overflow-wrap: break-word;
}
PostCSSプラグインの開発ガイドライン
PostCSSのプラグインを開発するためのガイドラインがあるので、そこからいくつか紹介します。
パッケージ名に postcss- プリフィックスを付ける
名前を明確にするために postcss- プリフィックスをパッケージに付けたほうが良いです。(e.g. postcss-mixins, postcss-simple-vars)ただし、Autoprefixerやstylelintのようにそれ自体がPostCSSのプラグインとしてだけではなく、独立したツールの場合は必須ではありません。
一つのことを上手くやる
Unix philosophy の1つですね。
postcss-pluginキーワードをpackage.jsonに書きましょう
npmパッケージとして作られる場合は、package.jsonにpostcss-pluginキーワードを指定することで、PostCSSエコシステムのフィードバックを受けやすくなります。npmパッケージとして公開しない場合は必須ではありません。
可能な限り非同期なメソッドを使いましょう
PostCSSのプラグインは順に読み込まれるため、プラグイン内で同期的なメソッドがあると処理がブロックされます。例えば、fs.writeFileSync() ではなく、fs.writeFile() を使うようにしましょう、ということです。
他
- プラグインのドキュメントは英語で書きましょう
- 入力と出力の例を書きましょう
- CHANGELOGをメンテナンスしましょう
- etc...
PostCSSプラグインの実装
それでは、overflow-wrap プロパティをフォールバックするPostCSSを作っていきましょう。パッケージ名を「postcsss-overflow-wrap」とします。
プラグインを作るときは、postcss.plugin(name, initializer) を module.exports します。postcss.plugin() はプラグイン名とプラグインの関数(ASTを受け取って変換し、ASTを返す関数)を引数にとり、プラグインを返します。
var postcss = require('postcss')
module.exports = postcss.plugin('postcss-overflow-wrap', function () {
return function (root) {
return root
}
})
そして、walkDecls()でプロパティを探索し、overflow-wrapプロパティを見つけたら、その直前にword-wrapプロパティを挿入します。
var postcss = require('postcss')
module.exports = postcss.plugin('postcss-overflow-wrap', function () {
return function (root) {
// overflow-wrapプロパティを探索し、
// 発見したら直前にword-wrapプロパティを挿入する
root.walkDecls(function (decl) {
if (decl.prop === 'overflow-wrap') {
decl.cloneBefore(decl.clone({ prop: 'word-wrap' }))
}
})
return root
}
})
これでpostcss-overflow-wrapは完成です。簡単ですね!
今日までで、PostCSSの仕組みとPostCSSのプラグインとはどういうものなのか、ということを理解していただけたのではと思います。明日からはPostCSSのプラグインとして有名なもの、便利なものを紹介していこうと思います。