gulpでサイト内のscssを同階層のcssにそれぞれ書き出す

2017.3.14 CSS

gulp-ruby-sass」使ってますか。

有名なパッケージですが、

サイトのディレクトリ構造次第で、コンパイルに手間がかかったりします。

例えば、僕の場合だと、サイト内の/scssディレクトリから、同階層の/cssディレクトリに書き出したいとき。

var dir = {
	top: '../root',
	below: '/',
	index: 'index.html'
	},
	sassDir = {
		css: 'css',
		scss: 'scss',
		dir: ''
	};
/**
* sass compile setting
* scss/ディレクトリのscssをコンパイルする
*/
gulp.task('sass' , function(){

 return sass( dir.top + `/【common/scss/など、特定のディレクトリをいちいち書く】/*.scss` , {
 compass : true,
 style: 'expanded'
 })
 .pipe(autoprefixer())
 .pipe(csscomb()) 
 .pipe(plumber({
 errorHandler : notify.onError('<%= error.message %>') //gulp notify エラーメッセージ
 }))
 .pipe(gulp.dest( dir.top + '/【/common/css/など、書き出し先をいちいち書く】'));

});

ある特定のscssディレクトリをウォッチしてdestしてました。これだと、間違ったコンパイルによる事故は起きませんが、違うページをコーディングするときgulpfile.jsを書き換えなくてはいけないので著しく効率が悪いです…

じゃあサイト全体の/scssディレクトリを、同じ階層内の/cssディレクトリに書き出せたらラクですよね。

サイト全体をウォッチして、scssディレクトリを、同じ階層のcssにそれぞれ書き出す方法をご紹介します。

ず

サイト全体のscssディレクトリを同階層のcssにコンパイルする

gulp-rename, gulp-ruby-sass をインストール

npm install gulp-rename --save-dev
npm install gulp-ruby-sass --save-dev

gulp-rename」を使用します。

gulpfile.jsでgulp-ruby-sassの設定

var gulp = require( 'gulp' );

//////////////////////////////////////////////////////
var browserSync = require( 'browser-sync' );
var autoprefixer = require( 'gulp-autoprefixer' );
var sass = require( 'gulp-ruby-sass' );
var plumber = require( 'gulp-plumber' );
var notify = require( 'gulp-notify' );
var rename = require( 'gulp-rename' );
var csscomb = require( 'gulp-csscomb' );
//////////////////////////////////////////////////////

var dir = {
	top: '../root',
	below: '/',
	index: 'index.html'
	},
	sassDir = {
		css: 'css',
		scss: 'scss',
		dir: ''
	};
/**
* sass compile setting
* scss/ディレクトリのscssをコンパイルする
*/
gulp.task('sass' , function(){

	return sass( dir.top + `/**/${sassDir.scss}/*.scss` , {
		compass : true,
		style: 'expanded'
	})
	.pipe(autoprefixer())
	.pipe(csscomb()) 
	.pipe(plumber({
		errorHandler : notify.onError('<%= error.message %>') //gulp notify エラーメッセージ
	}))
    .pipe(rename(function(path){
console.log('rename前',path)
      path.dirname = path.dirname.replace( sassDir.scss, sassDir.css); // scss→cssに 
      console.log('rename後',path);
    }))	
	.pipe(gulp.dest( dir.top ));

});
gulp.task('sassCompileReload' , ['sass'] , function(){
	browserSync.reload();
});

29行目 return sass(~~)

scssのディレクトリ指定には「/**/」ミニマッチを使います。
これは、ルートディレクトリ(root)と、scssディレクトリの間にディレクトリがいくつあっても、無くても対象としますよ、という宣言になります。つまり、サイト全体の各scssディレクトリをそれぞれコンパイルするということになります。

ただ、

39行目 .pipe(rename(function(path){ ~ })

ここが今回のテーマで重要な点です。

gulp-renameは書き出すファイルの名前を変えるのに用いられますが、ここでは、gulp-ruby-sassが書き出すディレクトリの指定を変えています。

rename関数で、書き出し先のパス情報を得ることができます。
引数「path」で受け取っていますが、試しにcommon/scss/style.scssを更新し、common/css/style.cssに変換したときのパス情報をconsole.logを使って見てみると

rename前,{ dirname: 'common/scss', basename: 'style', extname: '.css' }
rename後,{ dirname: 'common/css', basename: 'style', extname: '.css' }

こんな感じのオブジェクトを得ることができているのがわかります。

dirnameのところになんとなくそれっぽいのがありますね。dirnameこそが、書き出し先のディレクトリ名になります。

ここで、変換したscssを書き出すのを、同階層のcssディレクトリに指定しています。

return sass〜の記述のところでミニマッチ(/**/)を使った場合、コンパイルの対象が幅広くなり、非常に効率的です。

が、renameせずにそのままだと、階層構造を維持したままdestディレクトリにごっそりコピーされてしまい、意図しないところに書き出されてしまいます。

ず2

renameを使って、無理矢理変えてやろうという魂胆です。

scssとcssが同じディレクトリに存在する場合は今回のrenameは使わなくてもいいですね。

ウォッチタスクを忘れずに

/**
* default tasks
*/
gulp.task('default' ,['sassCompileReload'] ,  function(){
	gulp.watch( dir.top + '/**/scss/*.scss' , ['sassCompileReload']);

});

サイト内のscssディレクトリの、.scssファイルの更新をウォッチします。

 

まとめ

使う場所は限られているかもしれませんが…探しても載ってなかったので。(どうやって検索すれば良いかもわかりませんでしたが

同じように困ってる方の助けになれば幸いです。

 

でわ!

 

プロフィール

東京でWebデザイナー・コーダーとして、フロントエンド的なことからデザイン思考的なことを考えたりして、ごにょごにょと活動中。(ポートフォリオ)Webクリエイターでは珍しい(?) HIPHOP, R&B好き。休日はよくカフェや漫画喫茶に出向いたりパン屋に行ったりコーヒ豆買いに行ったり、主に散歩しています。。デザインのトレンドやデザイン思考、HTML、CSSからSASS、Javascript、Wordpress構築などコーディングのTIPSなどをブログにアップしていきます。その他のことはtwitter( @satohmsys )まで。コーヒー友達募集中。