gulp-compassのエラー時に、browser-syncによるリロードが止まる問題の解決方法


gulpでソースファイルに変更があった際、gulp-plumberを通したwatchタスク後にコールバックでbrowser-syncによるリロードをさせてましたが、
gulp-compassのエラー時のみ、リロードがされずに処理が止まる問題に悩まされていました。
scssファイルの変更は頻繁に確認するのでけっこう厄介な問題でしたが、最近解決したのでその方法を記しておこうと思います。

各プラグインのバージョン

[email protected](CLI, localともに)
[email protected]
[email protected]
[email protected]

原因

gulp-plumberに適切なエラー処理を書いてなかったのが原因でした。
gulp-plumberは特にエラー処理を指定しなくても動作することが多いですが、
gulp-compassと併用する際には以下のようにエラーハンドラを記述しないといけないようです。

gulpfile.js
var compass = require('gulp-compass'),
    plumber = require('gulp-plumber');

gulp.task('compass', function() {
  gulp.src('./src/*.scss')
     //.pipe(plumber()) // NG
    .pipe(plumber({ // OK
      errorHandler: function (error) {
        console.log(error.message);
        this.emit('end');
    }}))
    .pipe(compass({
      css: 'src/css',
      sass: 'src/sass',
    }))
    .pipe(gulp.dest('dist/assets/css'));
});

(あとで調べたらgulp-compass公式の下の方にplumberとの使い方が書いてあったのに気づきました…)

正直なところ、仕組みはよく分かってないのですが、this.emit('end')によって一旦watchタスクを終了させている?のがポイントのようです。

追記

後にgulp-lessでも似たようなエラーに遭遇し、同様の方法によって解決しました。
おまじない的な感じで、とりあえず上記エラーハンドラを書いておくといいのかもしれません。