Gulp 4: gulp.parallel gulp.series -- 全新的任务执行体系

Gulp 4 在任务执行体系上有一个很重要的改动,下面我们一起来看一下这个新的特性和如何从Gulp 3迁移到新版本

Gulp 3中的任务执行链

在了解新特性之前,让我们先看看之前是怎么做的。通常Gulp允许给task定义依赖(dependency),这保证了task执行之前它依赖的task已经获得执行。看下面代码:

 
  1. // 默认任务,执行scripts和styles这两个任务

  2. gulp.task('default', ['scripts', 'styles'], function() {...});

  3.  
  4. // scripts 和 styles 任务都调用了 clean 任务

  5. gulp.task('styles', ['clean'], function() {...});

  6. gulp.task('scripts', ['clean'], function() {...});

  7.  
  8. // Clean 任务清空了build目录

  9. gulp.task('clean', function() {...});

这是很典型的Gulpfile代码,你目的是执行scripts任务和styles任务,在此之前把build输出的目录清空以保证每次都都可以获得最新的build结果。这种语法很优雅,跟其他构建工具也类似。

当Gulp开始工作,它会创建一个任务依赖树,见下图。
folie1.jpg
它发现clean任务是另外两个task的依赖,从而确保clean只执行一次。

有一点需要注意:所有task都以最大并发量执行。它(default task)的执行顺序见下图:
folie2.jpg
首先执行clean任务,然后并行执行scriptsstyles任务。

这种方式有一些问题:

一旦你定义了上面的依赖链,依赖链的执行顺序就被确定了。

例如,给其中一个styles任务添加了监听(watcher)当css文件改变时重新执行styles任务,这时候就会出问题。想象一下,你每次改动了css文件就会触发styles任务,gulp会首先执行clean然后执行styles。如此一来,你构建打包的文件会因为clean任务执行被删除。

目前没有好的办法来顺序执行前面定义的各个task。“执行某一任务前先执行其依赖的任务” -- 这种执行方式导致了前面的问题。

有一个Gulp插件用来解决这个问题:run-sequence。它现在已经是Gulp 4的一部分了。

Gulp 4中的任务执行函数

Gulp 4抛弃了依赖参数(dependency parameter),用执行函数来代替:

  • gulp.series 用于串行(顺序)执行
  • gulp.parallel 用于并行执行

上面的两个函数接受两个参数:

  • 要执行的任务的名字
  • 需要执行的函数

如果你想并行执行scriptsstyles,你可以这么写:

gulp.task('default', gulp.parallel('scripts', 'styles'));

更棒的是,gulp.parallelgulp.series是函数,可以接受其它函数做参数,所以你可以随意嵌套使用它们,从而创建复杂的执行顺序。
folie4.jpg
上图的执行顺序是:A, 然后 B, 然后 C 和 D 并行执行, 最后 E。

从Gulp 3迁移到Gulp 4

尽量让任务以最大并发量执行可以提高执行效率,我们可以考虑把依赖的任务数组替换为gulp.parallel函数,最上面的任务代码可以改为像下面这样:

 
  1. gulp.task('styles', gulp.parallel('clean', function() {...}));

  2. gulp.task('scripts', gulp.parallel('clean', function() {...}));

  3.  
  4. gulp.task('clean', function() {...});

  5.  
  6. gulp.task('default', gulp.parallel('scripts', 'styles'));

这个方法的第一个问题是,执行scripts任务和styles任务时,clean任务会先执行。在并发的情况下,这意味着,执行styles时,可能把scripts任务的输出删掉。我们不想这样,让我们把上面的代码修改一下,使用gulp.series来创建串行执行的任务。

 
  1. gulp.task('styles', gulp.series('clean', function() {...}));

  2. gulp.task('scripts', gulp.series('clean', function() {...}));

  3.  
  4. gulp.task('clean', function() {...});

  5.  
  6. gulp.task('default', gulp.parallel('scripts', 'styles'));

这样好多了,然而还有需要解决的问题。首先,依赖仍然写死在了代码里,我们执行scripts或者styles时,clean任务会先被执行。其次,Gulp 4 不会进行依赖检查,我们的执行树(执行default task)看起来像这样:
folie3.jpg
clean任务被执行两次,这是致命的,因为有可能上一个任务的执行结果被下一个任务的执行删除。

为了做一次完美的健壮的迁移,实现最初的执行顺序,并且避免写死代码,我们可以这样做:

先来看一下最初的执行顺序:
folie2.jpg
default task的执行顺序是:先clean,然后stylesscripts并行执行。

每一个可以并发进行的步骤可以组合在gulp.parallel函数中,其余的任务按顺序放在gulp.series函数中,像这样:
folie5.jpg
对应的代码是:

 
  1. // 去掉了clean任务依赖

  2. gulp.task('styles', function() {...});

  3. gulp.task('scripts', function() {...});

  4.  
  5. gulp.task('clean', function() {...});

  6.  
  7. // Per default, start scripts and styles

  8. gulp.task('default',

  9. gulp.series('clean', gulp.parallel('scripts', 'styles'),

  10. function() {...}));

这样一来,default task的任务执行顺序就跟最初一样了。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
支援 Gulp 4.0,允许嵌套配置任务及组态。以优雅、直觉的方式,重复使用 gulp 任务。编码的时候你遵守 DRY 原则,那编写 gulpfile.js 的时候,为什么不呢?功能支援 Gulp 4.0,自动载入本地 recipe,支援透过 npm 安装 plugin,支援嵌套任务并且允许子任务继承组态配置,支援向前、向后参照任务,透过组态配置即可处理串流:譬如 merge, queue, 或者 concat,透过组态配置即可控制子任务执行parallel 或者 series,支援条件式组态配置,支援命令行指令,查询可用的 recpies 及使用方式,以及支援命令行指令,查询可用的任务说明及其组态配置。问与答问: gulp-chef 违反了 gulp 的『编码优于组态配置 (preferring code over configuration)』哲学吗?答: 没有, 你还是像平常一样编码, 并且将可变动部份以组态配置的形式萃取出来。 Gulp-chef 透过简化以下的工作来提高使用弹性:分割任务到不同的档案,以及让任务可分享并立即可用。问: 有其它类似的替代方案吗?答: 有,像 gulp-cozy, gulp-starter , elixir, 还有更多其他方案。问: 那么,跟其它方案比起来,gulp-chef 的优势何在?答:Gulp-chef 不是侵入式的。它不强迫也不限定你使用它的 API 来撰写通用任务 (recipe)。Gulp-chef 强大且易用。它提供了最佳实务作法,如:合并串流、序列串流等。这表示,你可以让任务『只做一件事并做好(do one thing and do it well)]』,然后使用组态配置来组合任务Gulp-chef 本身以及共享任务 (plugin) 都是标准的 node 模组。你可以透过 npm 安装并管理依赖关系,不再需要手动复制工具程式库或任务程式码,不再需要再担心忘记更新某个专案的任务,或者担心专案之间的任务版本因各自修改而导致不一致的状况。Gulp-chef 提供极大的弹性,让你依喜好方式决定如何使用它: 『最精简(minimal)』 或『最全面(maximal)』,随你选择。gulpfile.js 范例var gulp = require('gulp'); var chef = require('gulp-chef'); var ingredients = {     src: 'src/',     dest: 'dist/',     clean: {},     make: {         styles: {             recipe: 'copy',             src: '**/*.js'         },         browserify: {             bundle: {                 entry: 'main.js'             }         }     },     build: ['clean', 'make'],     default: 'build' }; var meals = chef(ingredients); gulp.registry(meals); 标签:gulpchef

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值