Gulp 4 在任务执行体系上有一个很重要的改动,下面咱们一块儿来看一下这个新的特性和如何从Gulp 3迁移到新版本
在了解新特性以前,让咱们先看看以前是怎么作的。一般Gulp容许给task定义依赖(dependency),这保证了task执行以前它依赖的task已经得到执行。看下面代码:css
// 默认任务,执行scripts和styles这两个任务 gulp.task('default', ['scripts', 'styles'], function() {...}); // scripts 和 styles 任务都调用了 clean 任务 gulp.task('styles', ['clean'], function() {...}); gulp.task('scripts', ['clean'], function() {...}); // Clean 任务清空了build目录 gulp.task('clean', function() {...});
这是很典型的Gulpfile代码,你目的是执行scripts
任务和styles
任务,在此以前把build输出的目录清空以保证每次都均可以得到最新的build结果。这种语法很优雅,跟其余构建工具也相似。gulp
当Gulp开始工做,它会建立一个任务依赖树,见下图。
它发现clean
任务是另外两个task的依赖,从而确保clean
只执行一次。数组
有一点须要注意:全部task都以最大并发量执行。它(default task)的执行顺序见下图:
首先执行clean
任务,而后并行执行scripts
和styles
任务。并发
这种方式有一些问题:函数
一旦你定义了上面的依赖链,依赖链的执行顺序就被肯定了。工具
例如,给其中一个styles
任务添加了监听(watcher)当css文件改变时从新执行styles
任务,这时候就会出问题。想象一下,你每次改动了css文件就会触发styles
任务,gulp会首先执行clean
而后执行styles
。如此一来,你构建打包的文件会由于clean
任务执行被删除。ui
目前没有好的办法来顺序执行前面定义的各个task。“执行某一任务前先执行其依赖的任务” -- 这种执行方式致使了前面的问题。spa
有一个Gulp插件用来解决这个问题:run-sequence
。它如今已是Gulp 4的一部分了。插件
Gulp 4抛弃了依赖参数(dependency parameter),用执行函数来代替:code
gulp.series
用于串行(顺序)执行gulp.parallel
用于并行执行上面的两个函数接受两个参数:
若是你想并行执行scripts
和styles
,你能够这么写:
gulp.task('default', gulp.parallel('scripts', 'styles'));
更棒的是,gulp.parallel
和gulp.series
是函数,能够接受其它函数作参数,因此你能够随意嵌套使用它们,从而建立复杂的执行顺序。
上图的执行顺序是:A, 而后 B, 而后 C 和 D 并行执行, 最后 E。
尽可能让任务以最大并发量执行能够提升执行效率,咱们能够考虑把依赖的任务数组替换为gulp.parallel
函数,最上面的任务代码能够改成像下面这样:
gulp.task('styles', gulp.parallel('clean', function() {...})); gulp.task('scripts', gulp.parallel('clean', function() {...})); gulp.task('clean', function() {...}); gulp.task('default', gulp.parallel('scripts', 'styles'));
这个方法的第一个问题是,执行scripts
任务和styles
任务时,clean
任务会先执行。在并发的状况下,这意味着,执行styles
时,可能把scripts
任务的输出删掉。咱们不想这样,让咱们把上面的代码修改一下,使用gulp.series
来建立串行执行的任务。
gulp.task('styles', gulp.series('clean', function() {...})); gulp.task('scripts', gulp.series('clean', function() {...})); gulp.task('clean', function() {...}); gulp.task('default', gulp.parallel('scripts', 'styles'));
这样好多了,然而还有须要解决的问题。首先,依赖仍然写死在了代码里,咱们执行scripts
或者styles
时,clean
任务会先被执行。其次,Gulp 4 不会进行依赖检查,咱们的执行树(执行default task)看起来像这样:clean
任务被执行两次,这是致命的,由于有可能上一个任务的执行结果被下一个任务的执行删除。
为了作一次完美的健壮的迁移,实现最初的执行顺序,而且避免写死代码,咱们能够这样作:
先来看一下最初的执行顺序:
default task的执行顺序是:先clean
,而后styles
和scripts
并行执行。
每个能够并发进行的步骤能够组合在gulp.parallel
函数中,其他的任务按顺序放在gulp.series
函数中,像这样:
对应的代码是:
// 去掉了clean任务依赖 gulp.task('styles', function() {...}); gulp.task('scripts', function() {...}); gulp.task('clean', function() {...}); // Per default, start scripts and styles gulp.task('default', gulp.series('clean', gulp.parallel('scripts', 'styles'), function() {...}));
这样一来,default task的任务执行顺序就跟最初同样了。