首页
技术分享
实用工具 发布文章 新浪微博 Github

Gulp 目前的错误处理方式有点操蛋,一旦发生错误进程就挂了,得手动去重启。虽然开发者预期在 gulp 4 中解决此问题,但 gulp 4 什么时候发布并没有明确时间表,在此之前,还是很有必要了解一下更优雅的错误处理方式,除非你钟情于反复在命令行里输入 gulp 然后回车。

1. 使用 Stream 事件 API 处理错误

Stream 发生错误时,会触发 error 事件,监听 error 事件进行错误处理可以避免 gulp 进程崩溃。

1.1 基本错误处理

下面的例子中,添加了 Less 编译的错误处理,Less 发生编译错误时,会在命令行输出错误信息,gulp 进程不会挂掉,修正错误后,watch 任务将继续执行。

注意:使用 gulp-util 只是使错误日志格式与 gulp 的日志保持一致,如果不想多一个依赖,可以直接使用 console

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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']);
});

1.2 gulp.watch 与 Browserify 中的错误处理

Browserify 中的常规流与 gulp 中的 vinyl 对象流有点不同,browserify 的错误处理中需要手动触发 end 事件,以停止流在管道中传送。如果不添加 this.emit('end');,进程仍然会挂掉。

1
2
3
4
5
6
7
8
9
10
11
12
13
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'));
});

2. 使用插件

使用 Stream 的事件 API 虽然可以处理错误,但是在每个插件后面都需要添加错误监听函数,有点恶心,还好有专门的插件处理这个问题。

2.1 gulp-plumber

gulp-plumber 可以阻止 gulp 插件发生错误导致进程退出并输出错误日志。

1
2
3
4
5
6
7
8
9
10
11
12
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'))
});

这比添加错误监听事件省事多了。

2.2 stream-combiner2

stream-combiner2 把多个 stream 合并为一个,也就是说只需要添加一个错误监听,相比之下,还是 gulp-plumber 方便。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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;
});

3. 参考链接

文章来源:https://csspod.com/error-management-in-gulp/