gulp + browserify(+ debowerify)という構成でWebサイトを作っていると、SASSにもdebowerify相当のものが欲しくなってくる。
ちなみに、debowerifyというのは、
var Velocity = require("velocity");
というJavascriptを、
var Velocity = require("./../../bower_components/velocity/velocity.js");
という風に、bower_components内のパスに解決してくれるbrowserify transformだ。
欲しいのはこれのSASS版。
「あったらいいのにな〜」と思うようなライブラリはGithubで検索すれば必ず出てくる。はずだったが、無かった。
そこで decomposer というgulpプラグインを作った。
使い方
まずはnpm install --save-dev gulp gulp-sass decomposer
で必要なものをインストールしておく。既存のプロジェクトに追加するならdecomposerだけでいい。
gulpfile.jsはこのように定義しておく。
var gulp = require('gulp');
var sass = require('gulp-sass');
var decomposer = require('decomposer');
gulp.task('styles', function() {
gulp.src('src/styles/**/*.sass')
.pipe(decomposer())
.pipe(sass({indentedSyntax: true}))
.pipe(gulp.dest('dist/css'));
});
ポイントはsass
よりも前にdecomposer
を挟むこと。なぜなら、外部から@importしたmix-insや変数はSASSコンパイル時に解決されるからだ。sass
よりも後に置くと、SASSが@importを解決出来ずにエラーが発生する。
続けてSASSを書こう。
@import normalize.sass
@import styles/font
body
font-family: $ff-gothic
$ff-gothic
は uetchy/styles の _font.sass で定義されているfont-familyだ。
最後にBowerを使って必要なアセットをインストールする。
$ bower i --save normalize.sass
$ bower i --save uetchy/styles
これで完成。後はgulp styles
を実行するだけだ。
ファイルパス解決時のポイント
decomposer はBowerモジュールに入っている任意のファイルを指定して@importすることが出来る。
記法はこのようになる。
@import [Bowerモジュール名]/[ファイル名]
例えば、よく使うスタイルをまとめた uetchy/styles の__font.sass_ を@importするなら、
@import styles/font
と書ける。
ここでもし@import styles
と、ファイル名を省略して書くとどうなるのだろうか?コンパイルに失敗する?そんなことはない。
モジュール名だけを書くと、decomposerはbower.jsonに書かれているmainファイルを見つけ出して、それを@importしてくれるのだ。
もしmainファイルが複数指定されていたら、index.sass
とか[モジュール名].sass
とか、mainっぽい名前を持つファイルを@importする。
つまり、
@import normalize.sass
と書けば、
@import ../bower_components/normalize.sass/normalize.sass
という風に解決される。
まとめ
これでスタイルの@importをすっきり書けるようになった。
とはいえ、component対応やPlain CSSのインライン展開、.less対応など、追加したい機能は色々ある。
もしContributionに興味があるなら、Githubリポジトリをフォークしてほしい。