kinalog

自称フロントエンドエンジニアが何か喚いています。

gulp-compassで色んな階層のsassをwatch

====================
2015.10.21 config.rbが使えるように改良した記事をアップしました。
====================




gulpの解説サイトを見ていると、そのどれもフォルダ構造が、フォルダ名は違えど

root(ここにgulpをインストール)
├ dist(ビルドするとここに出力される。サーバーにアップしたり納品用)
└ src(開発用)
  ├ assets(このフォルダ内にCSSや画像を全部突っ込む)
  │ ├ _sass
  │ ├ css
  │ ├ images
  │ └ js
  ├ index.html
  ・
  ・
  ・

みたいになっていますが、案件によっては

root
├ dist
└ src
  ├ assets(このフォルダ以下には共通のCSSやら画像やらのみ格納)
  │ ├ _sass
  │ ├ css
  │ ├ images
  │ └ js
  ├ _sass (トップページ用SASS)
  ├ css (トップページ用CSS)
  ├ images(トップページ用画像)
  ├ js(トップページ用JS)
  ├ index.html
  └ contents1
    ├ _sass(contents1用SASS)
    ├ css(contents1用CSS)
    ├ images(contents1用画像)
    ├  js(contents1用JS)
    └ index.html
    ・
    ・
    ・


みたいに、階層ごとにわけた構造にする必要が出てくることがあると思うんです。というか私はあります。

でもgulp-compassの公式のドキュメントを見ても、色々なサイトを見ても、rootフォルダでgulp watchしたとき下層の任意の場所でcompassを実行する方法っていうのがどうにも見当たらない。

ということで、どうやればいいか考えてみました。
※gulp超初心者のため、他にスマートな方法が存在しているかも。

使うプラグイン

gulpとgulp-compass、gulp-plumberは入れてある前提で...
(インストール方法は以前の記事で)

path
gulp-foreach

全部npm installしておく。

gulpfile.jsを変更

watchのとき実行されるcompassのタスクをこんな感じに。

// この辺は追記
var path = require('path');
var foreach = require('gulp-foreach');

// gulp watchで実行するタスク
gulp.task('compass-watch', function() {

    gulp.src('src/**/_sass')
        .pipe( foreach( function( stream, dir ) {
            var parent = path.dirname(dir.path); // 親のフォルダ名を取得

            return gulp.src( parent + '/_sass/**/' + '*.scss') // 今のフォルダ以下のscssに対して実行
                .pipe(plumber())
                .pipe(compass({
                    project: parent,
                    sass: '_sass',
                    css: 'css'
                }));
        } ) );
});

gulp-foreachは、指定してあげたファイルの分だけループするgulpプラグイン
最初はgulp.srcで指定してあげたファイルパスを普通に取得できないかなあと思っていたんだけど、どうにもやりかたが不明なためこちらを導入。

第2引数でファイルのオブジェクト(今回はフォルダだけど)を取得できるので、path.dirnameを用いて親フォルダのパスを取得。

後はcompassのタスクを実行するだけだけど、なんかconfig.rbを指定した状態だと上手く動かなかったので、オプションのprojectに親フォルダのパスを入れてやればそこがプロジェクトのルートフォルダとして認識される。


今のところはこれでいいけど、_sassフォルダが増えるととんでもなく重たくなりそうなのが懸念点。
まあそうなったら素直にパーツ類は全てassetsフォルダにまとめて管理、という方法がいいかもね。