在这样的代码片段中:
gulp.task "coffee", ->
gulp.src("src/server/**/*.coffee")
.pipe(coffee {bare: true}).on("error",gutil.log)
.pipe(gulp.dest "bin")
gulp.task "clean",->
gulp.src("bin", {read:false})
.pipe clean
force:true
gulp.task 'develop',['clean','coffee'], ->
console.log "run something else"
在develop
任务中,我希望运行clean
并在完成后运行coffee
并在完成后运行其他内容。但我无法弄明白。这件作品不起作用。请指教。
答案 0 :(得分:406)
默认情况下,gulp会同时运行任务,除非它们具有显式依赖关系。这对于clean
等您不想依赖的任务非常有用,但是您需要它们才能在其他任何事情之前运行。
我专门写了the run-sequence
plugin以解决这个问题。安装后,使用它:
var runSequence = require('run-sequence');
gulp.task('develop', function(done) {
runSequence('clean', 'coffee', function() {
console.log('Run something else');
done();
});
});
您可以阅读自述包README上的完整说明 - 它还支持同时运行一些任务集。
请注意,这将是(effectively) fixed in the next major release of gulp,因为它们完全取消了自动依赖关系排序,并提供类似于run-sequence
的工具,允许您手动指定运行顺序。
但是,这是一个重大的突破性变化,所以没有理由等到今天你可以使用run-sequence
。
答案 1 :(得分:370)
可以在gulp文档中找到解决此问题的唯一方法here
var gulp = require('gulp');
// takes in a callback so the engine knows when it'll be done
gulp.task('one', function(cb) {
// do stuff -- async or otherwise
cb(err); // if err is not null and not undefined, the orchestration will stop, and 'two' will not run
});
// identifies a dependent task must be complete before this one begins
gulp.task('two', ['one'], function() {
// task 'one' is done now
});
gulp.task('default', ['one', 'two']);
// alternatively: gulp.task('default', ['two']);
答案 2 :(得分:108)
它尚未正式发布,但即将推出的Gulp 4.0可让您轻松地与gulp.series进行同步任务。你可以这样做:
gulp.task('develop', gulp.series('clean', 'coffee'))
我发现了一篇很好的博客文章,介绍了如何升级和利用这些简洁的功能: migrating to gulp 4 by example
答案 3 :(得分:53)
我使用generator-gulp-webapp Yeoman生成器生成了一个node / gulp app。它处理了"干净的难题"这样(转换为问题中提到的原始任务):
gulp.task('develop', ['clean'], function () {
gulp.start('coffee');
});
答案 4 :(得分:31)
run-sequence是最明确的方式(至少在Gulp 4.0发布之前)
使用运行顺序,您的任务将如下所示:
var sequence = require('run-sequence');
/* ... */
gulp.task('develop', function (done) {
sequence('clean', 'coffee', done);
});
但如果您(出于某种原因)不想使用它, gulp.start
方法将有所帮助:
gulp.task('develop', ['clean'], function (done) {
gulp.on('task_stop', function (event) {
if (event.task === 'coffee') {
done();
}
});
gulp.start('coffee');
});
注意: 如果您只是在没有收听结果的情况下启动任务,develop
任务将在coffee
之前完成,这可能会令人困惑。
您可能还会在不需要时删除事件监听器
gulp.task('develop', ['clean'], function (done) {
function onFinish(event) {
if (event.task === 'coffee') {
gulp.removeListener('task_stop', onFinish);
done();
}
}
gulp.on('task_stop', onFinish);
gulp.start('coffee');
});
考虑您可能想听的task_err
事件。
成功完成后会触发task_stop
,而当出现错误时会显示task_err
。
您可能也想知道为什么没有gulp.start()
的官方文档。来自gulp成员的答案解释了这些事情:
gulp.start
有意无证,因为它可能导致复杂的构建文件,我们不希望有人使用它
(来源:https://github.com/gulpjs/gulp/issues/426#issuecomment-41208007)
答案 5 :(得分:26)
根据Gulp文档:
在依赖项完成之前,您的任务是否正在运行?确保您的依赖项任务正确使用异步运行提示:接受回调或返回承诺或事件流。
同步运行您的任务序列:
gulp.src
)返回gulp.task
以通知
流结束时的任务。gulp.task
的第二个参数中声明任务依赖项。参见修订后的代码:
gulp.task "coffee", ->
return gulp.src("src/server/**/*.coffee")
.pipe(coffee {bare: true}).on("error",gutil.log)
.pipe(gulp.dest "bin")
gulp.task "clean", ['coffee'], ->
return gulp.src("bin", {read:false})
.pipe clean
force:true
gulp.task 'develop',['clean','coffee'], ->
console.log "run something else"
答案 6 :(得分:9)
我遇到了同样的问题,解决方案对我来说非常简单。基本上将您的代码更改为以下,它应该工作。注意:gulp.src之前的返回对我来说完全不同。
gulp.task "coffee", ->
return gulp.src("src/server/**/*.coffee")
.pipe(coffee {bare: true}).on("error",gutil.log)
.pipe(gulp.dest "bin")
gulp.task "clean",->
return gulp.src("bin", {read:false})
.pipe clean
force:true
gulp.task 'develop',['clean','coffee'], ->
console.log "run something else"
答案 7 :(得分:7)
如果您实际查看Orchestrator源代码,特别是.start()
实现,您会看到如果最后一个参数是函数,它会将其视为回调函数。
我为自己的任务编写了这段代码:
gulp.task( 'task1', () => console.log(a) )
gulp.task( 'task2', () => console.log(a) )
gulp.task( 'task3', () => console.log(a) )
gulp.task( 'task4', () => console.log(a) )
gulp.task( 'task5', () => console.log(a) )
function runSequential( tasks ) {
if( !tasks || tasks.length <= 0 ) return;
const task = tasks[0];
gulp.start( task, () => {
console.log( `${task} finished` );
runSequential( tasks.slice(1) );
} );
}
gulp.task( "run-all", () => runSequential([ "task1", "task2", "task3", "task4", "task5" ));
答案 8 :(得分:3)
只需coffee
取决于clean
,而develop
取决于coffee
:
gulp.task('coffee', ['clean'], function(){...});
gulp.task('develop', ['coffee'], function(){...});
现在发送的是序列号:clean
→coffee
→develop
。请注意,clean
的实施和coffee
的实施必须接受回调,"so the engine knows when it'll be done":
gulp.task('clean', function(callback){
del(['dist/*'], callback);
});
总之,下面是同步clean
的简单gulp模式,后跟异步构建依赖:
//build sub-tasks
gulp.task('bar', ['clean'], function(){...});
gulp.task('foo', ['clean'], function(){...});
gulp.task('baz', ['clean'], function(){...});
...
//main build task
gulp.task('build', ['foo', 'baz', 'bar', ...], function(){...})
Gulp非常聪明,每clean
只运行一次build
,无论build
依赖项中有多少依赖于clean
。如上所述,clean
是同步障碍,然后所有build
的依赖项并行运行,然后运行build
。
答案 9 :(得分:3)
我正在寻找这个答案一段时间。现在我在官方的gulp文档中得到了它。
如果你想在最后一个任务完成时执行gulp任务,你必须返回一个流:
gulp.task('wiredep', ['dev-jade'], function () {
var stream = gulp.src(paths.output + '*.html')
.pipe($.wiredep())
.pipe(gulp.dest(paths.output));
return stream; // execute next task when this is completed
});
// First will execute and complete wiredep task
gulp.task('prod-jade', ['wiredep'], function() {
gulp.src(paths.output + '**/*.html')
.pipe($.minifyHtml())
.pipe(gulp.dest(paths.output));
});
答案 10 :(得分:3)
对我来说,连接后没有运行minify任务,因为它期望连接输入并且有时没有生成。
我尝试按执行顺序添加到默认任务,但它没有奏效。在为每项任务添加return
并在gulp.start()
内部进行缩小之后,它就起作用了。
/**
* Concatenate JavaScripts
*/
gulp.task('concat-js', function(){
return gulp.src([
'js/jquery.js',
'js/jquery-ui.js',
'js/bootstrap.js',
'js/jquery.onepage-scroll.js',
'js/script.js'])
.pipe(maps.init())
.pipe(concat('ux.js'))
.pipe(maps.write('./'))
.pipe(gulp.dest('dist/js'));
});
/**
* Minify JavaScript
*/
gulp.task('minify-js', function(){
return gulp.src('dist/js/ux.js')
.pipe(uglify())
.pipe(rename('ux.min.js'))
.pipe(gulp.dest('dist/js'));
});
gulp.task('concat', ['concat-js'], function(){
gulp.start('minify-js');
});
gulp.task('default',['concat']);
答案 11 :(得分:2)
Gulp和Node使用承诺。
所以你可以这样做:
// ... require gulp, del, etc
function cleanTask() {
return del('./dist/');
}
function bundleVendorsTask() {
return gulp.src([...])
.pipe(...)
.pipe(gulp.dest('...'));
}
function bundleAppTask() {
return gulp.src([...])
.pipe(...)
.pipe(gulp.dest('...'));
}
function tarTask() {
return gulp.src([...])
.pipe(...)
.pipe(gulp.dest('...'));
}
gulp.task('deploy', function deployTask() {
// 1. Run the clean task
cleanTask().then(function () {
// 2. Clean is complete. Now run two tasks in parallel
Promise.all([
bundleVendorsTask(),
bundleAppTask()
]).then(function () {
// 3. Two tasks are complete, now run the final task.
tarTask();
});
});
});
如果您返回gulp流,则可以使用then()
方法添加回调。或者,您可以使用Node的本机Promise
来创建自己的承诺。在这里,我使用Promise.all()
来获得一个在所有promises解析时触发的回调。
答案 12 :(得分:0)
要等任务是否完成然后再休息,我是这样的:
gulp.task('default',
gulp.series('set_env', gulp.parallel('build_scss', 'minify_js', 'minify_ts', 'minify_html', 'browser_sync_func', 'watch'),
function () {
}));
答案 13 :(得分:0)
我发现一个接一个地执行任务的非常简单有效的解决方案(当一个任务完成时,将启动第二个任务)(仅提供一个示例)是:
gulp.task('watch', () =>
gulp.watch(['src/**/*.css', 'src/**/*.pcss'], gulp.series('build',['copy'])) );
这意味着当您需要在 first-task
之前运行 second-task
时,您需要将第二个任务(在本例中为copy
)写在方括号中。
注意
任务的外部应该有圆括号(直到您希望它们同时发生)
答案 14 :(得分:-8)
试试这个黑客:-) Gulp v3.x Hack for Async bug
我在自述文件中尝试了所有“官方”方式,它们对我不起作用,但确实如此。你也可以升级到gulp 4.x,但我强烈建议你不要,它打破了很多东西。你可以使用真正的js承诺,但是嘿,这很快,很脏,很简单:-) 基本上你使用:
var wait = 0; // flag to signal thread that task is done
if(wait == 0) setTimeout(... // sleep and let nodejs schedule other threads
查看帖子!