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

Chr*_*ipp 9 watch typescript gulp

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

  • 皮棉
  • 建立
  • 测试

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

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

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

gulp.task("invalid-noemit", () =>
    gulp.src("input.ts")
        .pipe(tslint())
        .pipe(tslint.report("prose", {
          emitError: false
        }))
);
Run Code Online (Sandbox Code Playgroud)

但是当我包含该emitError标志时,会记录lint错误并执行所有后续gulp任务(构建,测试).

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

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

// watcher
gulp.task('watch', gulp.series('test', function doWatch() {
    gulp.watch([
        config.paths.sourcePattern,
        config.paths.testPattern,
        'gulpfile.js'
    ], gulp.parallel('test'));
}));
Run Code Online (Sandbox Code Playgroud)

你可以在gulpfile.js 这里找到完整的.

Sve*_*ung 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
    });
  });
});
Run Code Online (Sandbox Code Playgroud)

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

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

(旁白:观看gulpfile.js是没有用的。对 gulpfile 的更改只有在重新运行后才会生效gulp watch。没有办法解决这个问题。)


最后,您需要解耦其他任务,这样它们就不会显式依赖于其他任务。像这样翻译 gulp 3.x 任务是很诱人的:

gulp.task('foo', ['bar'], function() { });
Run Code Online (Sandbox Code Playgroud)

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

gulp.task('foo', gulp.series('bar', function() { }));
Run Code Online (Sandbox Code Playgroud)

它们表面上看起来很相似,但本质上却完全不同。有关该主题的更多信息,请参阅本文。

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

  1. 独立任务只做一件事,不依赖于其他任务。
  2. 串行或并行运行多个其他任务的复合任务。

遵循这一原则,您的其他任务可以重构为:

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() {
    /* ... */
}));
Run Code Online (Sandbox Code Playgroud)