当gulp任务失败时,Gulp会返回0。

35

我在我的小项目中使用Gulp来运行测试和代码检查。当其中任何一个任务失败时,Gulp总是以返回码0退出。如果我手动运行jshint,它将以非零的返回码退出,就像它应该做的那样。

这是我的非常简单的gulpfile

我需要某种方式明确告诉Gulp返回有意义的值吗?这是Gulp的问题,还是gulp-jshint和gulp-jasmine插件的问题?

6个回答

12

@robrich是正确的,你必须自己跟踪退出代码,但没有必要使用强制方式。全局的process是一个EventEmitter,您可以将退出函数绑定到其中。

var exitCode = 0

gulp.task('test', function (done) {
  return require('child_process')
    .spawn('npm', ['test'], {stdio: 'pipe'})
    .on('close', function (code, signal) {
      if (code) exitCode = code
      done()
    })
})

gulp.on('err', function (err) {
  process.emit('exit') // or throw err
})

process.on('exit', function () {
  process.nextTick(function () {
    process.exit(exitCode)
  })
})

2
为什么您要在gulp错误处理程序中触发退出事件,而不是直接调用process.exit呢? - Tiddo
Tiddo,上面的代码没有发出exit事件,而是在监听它。每当遇到一个exit事件时,它就会将process.exit(exitCode)排队等待在下一个tick上运行。 - Colton McCormack
3
太好笑了。 - nicolas

12

你需要在代码中添加'return gulp.src(...)'来使该任务等待返回的流。

编辑

Gulp 任务本质上是异步的。在'gulp.src(...).pipe(...);' 这一行代码被执行时,实际任务还没有开始执行。在你的示例中,gulp任务在实际任务执行之前就已经将其结果标记为成功。

有几种方法可以让gulp等待实际任务。使用回调函数、返回一个流或承诺。

https://github.com/gulpjs/gulp/blob/master/docs/API.md#async-task-support

最简单的方法就是返回 'gulp.src(...).pipe(...)' 的流。如果 gulp 任务获得了流,则会监听'end'事件和'error'事件,它们对应着返回码0和1。因此,关于您的 'lint' 任务的完整示例将如下所示:

gulp.task('lint', function () {
    return gulp.src('./*.js')
               .pipe(jshint('jshintrc.json'))
               .pipe(jshint.reporter('jshint-stylish'));
});

额外的好处是现在你可以测量你所花费的任务实际时间。


1
嗨,Shuhei,我尝试着返回这个数据流,但它也不起作用。感谢你提供的链接,我会仔细看看它。 - Roberto Bonvallet
嗨,Roberto,你可能需要失败报告器来使你的任务失败。 - Shuhei Kagawa

9

这个提交中,已经引入了一个修复方案。

它的工作原理大概是这样的:

gulp.src("src/**/*.js")
  .pipe(jshint())
  .pipe(jshint.reporter("default"))
  .pipe(jshint.reporter("fail"));

我一直在CircleCI上使用它,效果很好!


谢谢,这正是我最终期望发生的。 - Roberto Bonvallet
你知道Jasmine是否有类似的修复方法吗? - Roberto Bonvallet

4

gulp-jshint一直在努力解决如何在jshint失败时使构建失败的问题。一方面,我们可以在jshint内部崩溃构建,但这样你就无法获得报告器了。另一方面,要求报告器失败构建不是默认报告器的一部分。我通常会连接自己的报告器来跟踪失败,.on('end', function () {process.exit(1)。这相当于粗暴的力量,但它非常有效。请参见https://github.com/wearefractal/gulp-jshint/issues/10


2
嗨robrich,感谢您的参考。虽然我理解可能需要讨论如何失败和如何报告,但我认为返回非零值只是Unix的常规礼貌,因此应该是默认行为。我会尝试您的解决方法。 - Roberto Bonvallet

2

与上面Andy Piper的答案类似,我发现这个模块 stream-combiner2 在运行一系列任务时非常有用,以确保如果某处发生错误,则会发出退出代码。可以像这样使用

var combiner = require('stream-combiner2');

var tasks = combiner.obj([
    gulp.src(files),
    task1(options),
    task2(options),
    gulp.dest('path/to/dest')
]);

tasks.on('error', function () {
    process.exit(1)
});

0
gulp.task('default', function(done) {
  return gulp.src( ... ).pipe(jasmine( ... )).on('error', function(err) { done(err); } )
});

对我来说可行


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接