Gulp 4.0 前瞻

Gulp 4.0 发布在即,新首页已经上线,新版将会对任务系统做较大修改,(经过社区讨论——其实没什么讨论啦大家异口同声纷纷赞成。这是有多少不爽才会这样齐刷刷……)不再兼容 3.x 及之前版本的任务系统。

是不是摩拳擦掌跃跃欲试了?新 Gulp 玩起来~

新年新气象

先来看看新版有什么不同(CHANGELOG.md):

  • 新的任务系统(基于 bach,替换掉了原先基于 orchestrator 的任务系统)

    • 移除 gulp.reset
    • gulp.task 不再支持三个参数的用法
    • gulp.task 用字符串注册的任务必须是直接在命令行中调用的任务
    • gulp.task 可以接受单参数语法,这个参数必须是一个命名函数,函数名会被作为任务名
    • 添加了 gulp.seriesgulp.parallel 方法用于组合任务
    • 添加了 gulp.tree 方法用于获取任务树,传入 { deep: true } 参数可以得到一个 archy 兼容的节点列表
    • 添加了 gulp.registry 方法以定制注册表。
  • 添加了 gulp.symlink 方法,功能和 gulp.dest 一致,不过是以软链接的方式
  • gulp.destgulp.symlink 方法添加了 dirMode 参数允许对目标目录更好地控制
  • gulp.src 接收的文件匹配字符串会顺序解释,所以你可以写成这样 gulp.src(['*.js', '!b*.js', 'bad.js'])(排除所有以 b 开头的 JS 文件但是除了 bad.js)
  • gulp.src 方法添加了 since 选项,筛选在特定时间点之后修改过的文件(用于增量编译)
  • 将命令行分离出来成为一个独立模块,以便节约带宽/空间。用 npm install gulp -gnpm install gulp-cli -g 都可以安装命令行,只是 gulp-cli 不包含模块代码所以比较小
  • 命令行添加了 --tasks-json 参数,可以导出整个任务树以供他用
  • 命令行添加了 --verify 参数用以检查 package.json 中是否包含黑名单插件(违背准则而被禁入官方插件列表的可怜娃们)。

新的 gulp.task

从 3.x 升级到 4.x 主要做的就是修改任务定义,以前的任务是这么写的:

javascriptgulp.task('build', function(){
  gulp.src(['*.js'])
    .pipe(concat('libs.js'))
    .pipe(uglify())
    .pipe(gulp.dest('dist'));
});

gulp.task('default', ['build']);

这里 build 任务的写法在 Gulp 4.0 下还是OK的,default 就不行了,要改成这样:

javascriptgulp.task('default', gulp.parallel('build'));

好像多了13个字符……莫急。如果想要做个 clean-build 呢?以前要这样:

javascriptgulp.task('clean', function(){
  del('dist');
});

gulp.task('build', function(){
  gulp.src(['*.js'])
    .pipe(concat('libs.js'))
    .pipe(uglify())
    .pipe(gulp.dest('dist'));
});

gulp.task('clean-build', ['clean'], function(){
  gulp.start('build');
});

gulp.task('default', ['build']);

按新的写法,cleanbuild 还是照旧,clean-builddefault 略有不同:

javascriptgulp.task('clean', function(){
  del('dist');
});

gulp.task('build', function(){
  gulp.src(['*.js'])
    .pipe(concat('libs.js'))
    .pipe(uglify())
    .pipe(gulp.dest('dist'));
});

gulp.task('clean-build', gulp.series('clean', 'build'));
gulp.task('default', gulp.parallel('build'))

这其中 cleanbuild 任务可以写成独立的函数:

javascriptfunction clean(){
  del('dist');
}

function build(){
  gulp.src(['*.js'])
    .pipe(concat('libs.js'))
    .pipe(uglify())
    .pipe(gulp.dest('dist'));
}

gulp.task(clean);
gulp.task(build); // 也可以取个更酷的名字 gulp.task('super-fast-building', build);
gulp.task('clean-build', gulp.series(clean, build));
gulp.task('default', gulp.parallel(build)); // 只有一个任务的时候 `parallel` 和 `series` 都行

是不是感觉漂亮多了?任务的操作内容和相互间的依赖顺序都更加清晰。

不过……你只要不是特别粗糙,都会发现现在执行任务只有开始没有结束了:

bash$ gulp
[22:07:25] Using gulpfile ~/project/gulpfile.js
[22:07:25] Starting 'default'...
[22:07:25] Starting 'clean'...
[22:07:25] Starting 'build'...

$ # What are you waiting for?

因为我们还没写完:P,现在更赞的来了。任务函数可以接受一个 callback 作为参数,只有当你调用了这个 callback,这个任务才算结束:

javascriptfunction clean(callback){
  del('dist', callback);
}

function build(callback){
  gulp.src(['*.js'])
    .pipe(concat('libs.js'))
    .pipe(uglify())
    .pipe(gulp.dest('dist'))
    .on('finish', callback);
}

gulp.task(clean);
gulp.task(build);
gulp.task('clean-build', gulp.series(clean, build));
gulp.task('default', gulp.parallel(build));

从此你再也不会看到 default 任务先完成,然后才执行一大串 cleanbuild...,然后再等个三分钟,图片目录的压缩才结束的穿帮剧情了。最奇葩的是,Gulp 还说每个任务执行时间都不到10毫秒……谁信!

到了 4.0,这事情终于完美了:

bash$ gulp
[22:07:25] Using gulpfile ~/project/gulpfile.js
[22:07:25] Starting 'default'...
[22:07:25] Starting 'clean'...
[22:07:25] Finished 'clean' after 33 ms
[22:07:25] Starting 'build'...
[22:07:25] Finished 'build' after 437 ms
[22:07:25] Finished 'default' after 471 ms

试用 Gulp 4.0

虽然它还没有正式发布,但是阻挡不了我们尝鲜的脚步。只要如此这般:

bash# 如果安装过全局的 gulp 的话先卸载之
$ npm uninstall gulp -g

# 安装全局的 gulp 4.0
$ npm install "gulpjs/gulp#4.0" -g

# 到项目目录里删掉本地的 gulp
$ npm rm gulp --save-dev

# 安装本地的 gulp 4.0
$ npm install "gulpjs/gulp#4.0" --save-dev

作为起步,这儿有一个 4.0 的 gulpfile.js 可以参考学习。开始爽起来吧!

如果觉得我的文章对你有用,请随意赞赏

你可能感兴趣的文章

17 条评论
PynixWang · 2015年02月02日

命名函数 coffee悲剧了

+2 回复

灯盏细辛 · 2015年02月03日

穿帮剧情是因为你没任务都没return

+1 回复

xctk · 2015年02月03日

不再兼容 3.x 及之前版本的任务系统。。。

回复

Riophae · 2015年02月08日

不要全局安装 gulpjs 啊…

回复

Amio 作者 · 2015年02月09日

很多时候是因为任务内部的执行是异步的,return 也没用,除非用 Promise 一层层包起来

回复

Joenil · 2015年03月21日

gulp.task('clean-build', gulp.series('clean', 'build'));这个在3.x里不是可以这样写吗:
gulp.task('clean-build',[ 'clean', 'build']);4.0干嘛要搞这么麻烦

回复

Amio 作者 · 2015年03月26日

在 3.x 里这么写 clean 和 build 会并行执行,而不是串行,你有可能会发现有一些 build 结果被 clean 删掉了

回复

Amio 作者 · 2015年03月30日

全局的 gulp 命令只是个 launcher,执行的 gulp 主体还是 local 这份。

为了解决新老版本兼容问题,gulp 参照 grunt 也分离出来一个独立的 gulp-cli,不过目前 gulp-cli 只能跟 3.x 的 local gulp 协作,本地如果是 4.0 的话会报错,得等到 gulpjs 的 4.0 合并到 master 分支才行(具体原理不详)。

好在目前 global 的 gulp 4.0 跟 local 的 3.x 或 4.x 都兼容,所以全局安装 gulp4 尽管放心 :D

回复

Riophae · 2015年03月30日

嗯嗯我之前试过了,木有问题~~

回复

Humphry · 2015年09月24日

“发布在即”,然则半年过去了……

回复

Amio 作者 · 2015年09月24日

那还是在今年的1月30号,Gulp 作者说“本来31号要发布4.0的,但是我感冒了,所以推迟几天,抱歉伙计们”,然后就没有然后了……https://twitter.com/contrahacks/status/560936371012263936

回复

Humphry · 2015年09月24日

幼小的心灵受到了伤害T_T

回复

真嗣同学 · 2015年11月19日

bower终止开发了……4.0发布了……这个例子可以改改了

回复

Amio 作者 · 2015年11月21日

还没,4.0 还没正式呢……虽然已经11月了

回复

88888888888888888 · 2015年12月17日

爽一爽先,,

回复

88888888888888888 · 2016年01月15日
我了个去..在win下4.0很好用 切带linux挂了

= =CLI忘记一起切到4了.是可以的

回复

执剑为何 · 2016年03月11日

一年了吧,4.0还没发布吧

回复

载入中...
Amio Amio

1k 声望

发布于专栏

Coding Amio

哎哟……

15 人关注