This is a common issue people run into with Gulp, especially when coming from Grunt. Gulp is async to the max, it always wants to do as many things as it can all at the same time.
The first step to getting tasks to run sequentially is to let gulp know when your task ends, this can be done a couple different ways.
1) Return a stream, gulp will wait for the stream's "end" event as the trigger for that task being done. Example:
gulp.task( "stream-task", function(){
return gulp.src( srcGlob )
.pipe(sass())
.pipe(compressCSS())
.pipe(gulp.dest( destGlob ));
});
2) Return a Promise, gulp will wait for the promise to enter a resolved state before signaling the task as done. Example: (not perfect just to get the point across)
gulp.task( "promise-task", function() {
return new Promise(function(resolve, reject){
fs.readFile( "filename", function( err, data ){
if( err ){ return reject(err); }
return resolve( data );
});
});
});
3) Call the task callback, if the function doesn't return anything but the function signature takes an argument, that argument will be a callback function you can call to signal the task as done. Example:
gulp.task( "cb-task", function( done ){
fs.readFile( "filename", function( err, data ){
// do stuff, call done...
done();
});
});
Most often you are going to be returning a stream like example 1, which is what a typical gulp task looks like. Options 2 and 3 are more for when you are doing something that isn't really a traditional stream based gulp task.
The next thing is setting the "dependency" of one task for another. The gulp docs show this as the way you do that:
gulp.task( "some-task-with-deps", [ "array-of-dep", "task-names" ], function(){ /* task body */ });
Now I don't know the current status but there were some issues with these dependency tasks not running in the proper order. This was originally caused by a problem with one of gulp's dependencies (orchestrator I believe). One kind gentleman out there in NPM land made a nice little package to be used in the interim while the bugs were being worked out. I started using it to order my tasks and haven't looked back.
https://www.npmjs.com/package/run-sequence
The documentation is good so I won't go into a lot of detail here. Basically run-sequence
lets explicitly order your gulp tasks, just remember it doesn't work if you don't implement one of the three options above for each of your tasks.
Looking at your gist adding a couple missing return statements in your tasks may just do the trick, but as an example this is what my "dev" task looks like for my project at work...
gulp.task( "dev", function( done ){
runSequence(
"build:dev",
"build:tests",
"server:dev",
[
"less:watch",
"jscs:watch",
"lint:watch",
"traceur:watch"
],
"jscs:dev",
"lint:dev",
"tdd",
done // <-- thats the callback method to gulp let know when this task ends
);
});
Also for reference my "build:dev" task is another use of run-sequence
gulp.task( "build:dev", function( done ){
runSequence(
"clean:dev",
[
"less:dev",
"symlink:dev",
"vendor:dev",
"traceur:dev"
],
done // <-- thats the callback method to let know when this task ends
);
});
If the tasks need to be run in order the task name gets added as its own argument to runSequence
if they don't conflict send them in as an array to have the tasks run at the same time and speed up your build process.
One thing to note about watch tasks! Typically watch tasks run indefinitely so trying to return the "infinite" stream from them may make gulp think that the task never ends. In that case I'll use the callback method to make gulp think the task is done even if it is still running, something like...
gulp.task( "watch-stuff", function( done ){
gulp.watch( watchGlob )
.on( "change", function( event ){ /* process file */ });
done();
});
For more on watch tasks and how I do incremental builds check out an answer I wrote the other day, Incremental gulp less build