gulp-ruby-sass 1.0.0 から記述方法が変わるらしい

先日、gulp-ruby-sass 1.0.0-alpha にアップデートしたところ、Sass のコンパイルがエラーでコケるようになりました。

半年前に書いたgulp-ruby-sass 0.6 にアップデートしたらコケた話のように、オプションの指定方法が変わったのかな?と思いつつ公式リポジトリを確認したところ、タスク自体の書式が変わるようです。

sindresorhus/gulp-ruby-sass at rw/1.0:
https://github.com/sindresorhus/gulp-ruby-sass/tree/rw/1.0

今後 1.0 未満のバージョンはサポートされないようですので、覚えておくとよさそうです。

やったこと

まず、gulp-ruby-sass 1.0.0-alpha にアップデートします。

$ npm update gulp-ruby-sass

自分の場合、個別にアップデートするのではなく npm-check-updates を利用しています。

npm-check-updates で package.json を更新する:
https://bunlog.dreamseeker.dev/2014/07/22/autoupdate-package_json/

次に、gulpfile.js へ定義済みのタスクを書き換えます。

変更前の task.sass

gulp.task('sass', function(){
  return gulp.src(['*.scss'], {cwd: dir.src + '/' + dir.scss})
             .pipe($.rubySass({
               loadPath: process.cwd() + '/' + dir.src + '/' + dir.scss
             }))
             .pipe(gulp.dest(dir.src + '/' + dir.css));
});

gulp.src で対象となるディレクトリやファイルを指定し、.pipe で gulp-ruby-sass を繋げています。

変更後の task.sass

gulp.task('sass', function (){
  return $.rubySass(dir.src + '/' + dir.scss + '/publish/', {
            loadPath: process.cwd() + '/' + dir.src + '/' + dir.scss
          })
          .on('error', function (err) { console.log(err.message); })
          .pipe(gulp.dest(dir.src + '/' + dir.css));
});

gulp-ruby-sass 1.0.0 以降は、プラグインの第一引数にセットする形になります。

ディレクトリを指定する場合、内包する .scss はすべて対象となるため、処理したいファイルのみ /publish/ に移動することにしました。loadPath をセットしておけば、個々の .scss へ記述した @import のパスを書き換える必要がないので、あとで元の階層に戻すことにしても手間は少なそうです。

参考

余談になりますが、自分なりに試してダメだった例を晒しておきます w

ファイル名にアスタリスクや配列を利用する

// アスタリスクで指定
gulp.task('sass', function (){
  return $.rubySass(dir.src + '/' + dir.scss + '/*.scss', {
            loadPath: process.cwd() + '/' + dir.src + '/' + dir.scss
          })
          .on('error', function (err) { console.log(err.message); })
          .pipe(gulp.dest(dir.src + '/' + dir.css));
});

// 配列で指定
gulp.task('sass', function (){
  return $.rubySass([dir.src + '/' + dir.scss + '/foo.scss', dir.src + '/' + dir.scss + '/bar.scss'], {
            loadPath: process.cwd() + '/' + dir.src + '/' + dir.scss
          })
          .on('error', function (err) { console.log(err.message); })
          .pipe(gulp.dest(dir.src + '/' + dir.css));
});

あとから気づいたのですが、公式リポジトリの Usage 欄に「Note: gulp-ruby-sass doesn't support globs yet.」と記載されているため、いずれこんな感じで指定できるようになりそうです。

ファイル一覧を取得してループ処理する

// function.getFiles
var getFiles = function (dir) {
  return fs.readdirSync(dir)
           .filter(function (file) {
             return fs.statSync(path.join(dir, file)).isFile();
           });
}

// task.sass
gulp.task('sass', function (){
  var srcDir  = dir.source + '/' + dir.scss;
  var destDir = dir.source + '/' + dir.css;
  var files   = getFiles(srcDir);

  files.map(function (file) {
    if(file.indexOf('.scss') > -1 && file.charAt(0) != '_'){
      $.rubySass(path.join(srcDir, file), {
         loadPath: process.cwd() + '/' + srcDir
       })
       .on('error', function (err) { console.log(err.message); })
       .pipe(gulp.dest(destDir));
    }
  });
});

Sass のディレクトリ直下にある .scss(ファイル名が _ で始まるものを除く)は取得できているのですが、2つめのファイル処理で stderr とのこと。