Gulp watch 终止或构建整个任务链
Gulp watch terminates or builds the whole task chain
我正在使用以下构建步骤开发打字稿项目:
- lint
- 建设
- 测试
我正在使用 Gulp 4.0 作为构建工具,并希望有一个 watch 任务,它应该会触发测试(这意味着 lint 和构建任务会先触发)。当前,当发生错误(例如 lint 错误)时,监视任务将终止。
这个问题众所周知,也很容易解决。典型的解决方案是 a) 防止错误或 b) 修补管道行为。
a) 对于 gulp-tslint 我可以从他们的主页使用这个配置:
gulp.task("invalid-noemit", () =>
gulp.src("input.ts")
.pipe(tslint())
.pipe(tslint.report("prose", {
emitError: false
}))
);
但是当我包含 emitError
标志时,会记录 lint 错误并执行所有后续 gulp 任务(构建、测试)。
b) 我也可以使用 gulp-plumber
或手动捕获错误(参见 here),但所有这些已知解决方案的行为都是相同的,以下 gulp 任务是已执行(构建、测试)。
我想要的是任务链在出错后停止(lint 错误后没有构建和测试),但监视任务永远不会停止。我该如何解决这个问题?观察者任务如下所示:
// watcher
gulp.task('watch', gulp.series('test', function doWatch() {
gulp.watch([
config.paths.sourcePattern,
config.paths.testPattern,
'gulpfile.js'
], gulp.parallel('test'));
}));
您可以找到完整的 gulpfile.js
here。
您的手表停止的原因是 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')
实际上并未执行任务。它只是 returns 一个接受回调的新函数。只有当这个新函数被调用为 gulp.series('lint', 'build', 'test')()
时,任务才会真正执行。
我还添加了 ignoreInitial
选项,以便 watch 在启动后执行一次,这似乎是您在 watch
任务中使用 gulp.series('test', ...)
试图实现的。
(旁白:观看 gulpfile.js
是没有用的。对 gulp 文件的更改只有在您重新 运行 gulp watch
后才会生效。没有办法解决这个问题。 )
最后你需要解耦你的其他任务,所以它们对其他任务没有明确的依赖性。像这样翻译 gulp 3.x 任务很诱人:
gulp.task('foo', ['bar'], function() { });
进入这样的 gulp 4.x 任务:
gulp.task('foo', gulp.series('bar', function() { }));
它们表面上看起来很相似,但在本质上却完全不同。有关该主题的更多信息,请参阅 this article。
一个好的策略是将您的任务分为两类:
- 独立任务 只做一件事而不依赖于其他任务。
- 复合任务 运行 几个其他任务串联或并行。
遵循这个原则,您的其他任务可以重构为:
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() {
/* ... */
}));
我正在使用以下构建步骤开发打字稿项目:
- lint
- 建设
- 测试
我正在使用 Gulp 4.0 作为构建工具,并希望有一个 watch 任务,它应该会触发测试(这意味着 lint 和构建任务会先触发)。当前,当发生错误(例如 lint 错误)时,监视任务将终止。
这个问题众所周知,也很容易解决。典型的解决方案是 a) 防止错误或 b) 修补管道行为。
a) 对于 gulp-tslint 我可以从他们的主页使用这个配置:
gulp.task("invalid-noemit", () =>
gulp.src("input.ts")
.pipe(tslint())
.pipe(tslint.report("prose", {
emitError: false
}))
);
但是当我包含 emitError
标志时,会记录 lint 错误并执行所有后续 gulp 任务(构建、测试)。
b) 我也可以使用 gulp-plumber
或手动捕获错误(参见 here),但所有这些已知解决方案的行为都是相同的,以下 gulp 任务是已执行(构建、测试)。
我想要的是任务链在出错后停止(lint 错误后没有构建和测试),但监视任务永远不会停止。我该如何解决这个问题?观察者任务如下所示:
// watcher
gulp.task('watch', gulp.series('test', function doWatch() {
gulp.watch([
config.paths.sourcePattern,
config.paths.testPattern,
'gulpfile.js'
], gulp.parallel('test'));
}));
您可以找到完整的 gulpfile.js
here。
您的手表停止的原因是 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')
实际上并未执行任务。它只是 returns 一个接受回调的新函数。只有当这个新函数被调用为 gulp.series('lint', 'build', 'test')()
时,任务才会真正执行。
我还添加了 ignoreInitial
选项,以便 watch 在启动后执行一次,这似乎是您在 watch
任务中使用 gulp.series('test', ...)
试图实现的。
(旁白:观看 gulpfile.js
是没有用的。对 gulp 文件的更改只有在您重新 运行 gulp watch
后才会生效。没有办法解决这个问题。 )
最后你需要解耦你的其他任务,所以它们对其他任务没有明确的依赖性。像这样翻译 gulp 3.x 任务很诱人:
gulp.task('foo', ['bar'], function() { });
进入这样的 gulp 4.x 任务:
gulp.task('foo', gulp.series('bar', function() { }));
它们表面上看起来很相似,但在本质上却完全不同。有关该主题的更多信息,请参阅 this article。
一个好的策略是将您的任务分为两类:
- 独立任务 只做一件事而不依赖于其他任务。
- 复合任务 运行 几个其他任务串联或并行。
遵循这个原则,您的其他任务可以重构为:
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() {
/* ... */
}));