Gulp watch终止或构建整个任务链

时间:2016-06-03 06:09:56

标签: typescript gulp watch

我正在使用以下构建步骤开发一个打字稿项目:

  • 棉绒
  • 构建
  • 测试

我正在使用Gulp 4.0作为构建工具,并希望有一个监视任务,它应该触发测试(这意味着先前已触发lint和构建任务)。目前,当发生错误(例如lint错误)时,监视任务终止。

这个问题众所周知,易于解决。典型的解决方案是a)防止错误或b)修补管道行为。

a)对于gulp-tslint我可以在他们的主页上使用此配置:

using static

但是当我包含gulp.task("invalid-noemit", () => gulp.src("input.ts") .pipe(tslint()) .pipe(tslint.report("prose", { emitError: false })) ); 标志时,会记录lint错误并执行所有后续gulp任务(构建,测试)。

b)我也可以手动使用emitError或捕获错误(参见here),但所有这些已知解决方案的行为相同,执行以下gulp任务(构建,测试)

我想要的是任务链在发生错误后停止(在lint错误之后没有构建和测试),但是watch任务永远不会停止。我该怎么解决这个问题?观察者任务看起来像这样:

gulp-plumber

您可以找到完整的// watcher gulp.task('watch', gulp.series('test', function doWatch() { gulp.watch([ config.paths.sourcePattern, config.paths.testPattern, 'gulpfile.js' ], gulp.parallel('test')); })); here

1 个答案:

答案 0 :(得分:2)

您的观看停止的原因是因为err对象在回调链中向上传播。您必须阻止err到达最终的gulp.watch()回调。

您可以通过包装gulp.watch()提供的回调并且永远不会将err对象传递给原始回调来执行此操作:

gulp.task('watch', function() {
  gulp.watch([
      config.paths.sourcePattern,
      config.paths.testPattern,
      'gulpfile.js'
    ], {ignoreInitial:false}, function(cb) {
      gulp.series('lint', 'build', 'test')(function wrappedCb(err) {
        cb(); // not passing err here
    });
  });
});

请注意gulp.series('lint', 'build', 'test')实际上并不执行任务。它只返回一个接受回调的新函数。只有当这个新函数被调用为gulp.series('lint', 'build', 'test')()时,才会执行实际执行的任务。

我还添加了ignoreInitial选项,以便在启动后执行一次监视,这似乎是您在gulp.series('test', ...)任务中watch尝试实现的目标。

(旁白:看gulpfile.js没用。在重新运行gulp watch之前,对gulpfile的更改不会生效。没有办法解决这个问题。)

最后,您需要解除其他任务,因此他们没有明确依赖其他任务。像这样翻译gulp 3.x任务很有吸引力:

gulp.task('foo', ['bar'], function() { });

像这样进入gulp 4.x任务:

gulp.task('foo', gulp.series('bar', function() { }));

它们在表面上看起来很相似,但它们在引擎盖下完全不同。有关该主题的更多信息,请参阅this article

一个好的策略是将您的任务分为两类:

  1. 独立任务做一件事,不依赖于其他任务。
  2. 复合任务,可以串行或并行运行其他几项任务。
  3. 遵循这一原则,您的其他任务可以重构为:

    gulp.task('lint', function() {
      return gulp.src([
        config.paths.sourcePattern,
        config.paths.testPattern
      ])
      .pipe(tslint())
      .pipe(tslint.report('verbose', {
        emitError: true, // we WANT to emit this err so our other tasks don't run
        summarizeFailureOutput: true
      }));
    });
    
    gulp.task('build-app', function doBuildApp() {
      /* ... */
    });
    
    gulp.task('build-test', function doBuildTest() {
      /* ... */
    });
    
    gulp.task('build', gulp.series('lint', 'build-app', 'build-test'));
    
    gulp.task('test', gulp.series(function doPreTest() {
        /* ... */
      }, function doTest() {
        /* ... */
      }, function doPostTest() {
        /* ... */
    }));