Gulp 目前的錯誤處理方式有點操蛋,一旦發生錯誤進程就掛了,得手動去重啓。雖然開發者預期在 gulp 4 中解決此問題 ,但 gulp 4 何時發佈並無明確時間表,在此以前,仍是頗有必要了解一下更優雅的錯誤處理方式,除非你鍾情於反覆在命令行裏輸入 gulp
而後回車。javascript
Stream 發生錯誤時,會觸發 error
事件,監聽 error
事件進行錯誤處理能夠避免 gulp 進程崩潰。css
下面的例子中,添加了 Less 編譯的錯誤處理,Less 發生編譯錯誤時,會在命令行輸出錯誤信息,gulp 進程不會掛掉,修正錯誤後,watch 任務將繼續執行。html
注意:使用 gulp-util 只是使錯誤日誌格式與 gulp 的日誌保持一致,若是不想多一個依賴,能夠直接使用 console
。java
var gulp = require('gulp'); var less = require('gulp-less'); var csso = require('gulp-csso'); var gutil = require('gulp-util'); gulp.task('less', function() { return gulp.src('less/app.less') .pipe(less()) .on('error', function(err) { gutil.log('Less Error!', err.message); this.end(); }) .pipe(csso()) .pipe(gulp.dest('./dist')) }); gulp.task('watch', function() { gulp.watch('less/**/*.less', ['less']); });
gulp.watch 與 Browserify 中的錯誤處理node
Browserify 中的常規流與 gulp 中的 vinyl 對象流有點不一樣,browserify 的錯誤處理中須要手動觸發 end
事件 ,以中止流在管道中傳送。若是不添加 this.emit('end');
,進程仍然會掛掉。git
var gulp = require('gulp'); var browserify = require('browserify'); var source = require("vinyl-source-stream"); gulp.task('browserify', function(){ return browserify('./main.js').bundle() .on('error', function(err){ console.log(err.message); this.emit('end'); }) .pipe(source('main.out.js')) .pipe(gulp.dest('./dist')); });
使用插件github
使用 Stream 的事件 API 雖然能夠處理錯誤,可是在每一個插件後面都須要添加錯誤監聽函數,有點噁心,還好有專門的插件處理這個問題。npm
gulp-plumber 能夠阻止 gulp 插件發生錯誤致使進程退出並輸出錯誤日誌。gulp
var gulp = require('gulp'); var less = require('gulp-less'); var csso = require('gulp-csso'); var plumber = require('gulp-plumber'); gulp.task('less', function() { return gulp.src('less/app.less') .pipe(plumber()) .pipe(less()) .pipe(csso()) .pipe(gulp.dest('./dist')) });
這比添加錯誤監聽事件省事多了。bootstrap
stream-combiner2 把多個 stream 合併爲一個,也就是說只須要添加一個錯誤監聽,相比之下,仍是 gulp-plumber 方便。
var combiner = require('stream-combiner2'); var uglify = require('gulp-uglify'); var gulp = require('gulp'); gulp.task('test', function() { var combined = combiner.obj([ gulp.src('bootstrap/js/*.js'), uglify(), gulp.dest('public/bootstrap') ]); // any errors in the above streams will get caught // by this listener, instead of being thrown: combined.on('error', console.error.bind(console)); return combined; });