每年培训输出1000+合格IT工程师
培训影响全国各大知名IT企业和部门

gulp 4.0 升级指南

gulp简介

- 自动化 - gulp是一个工具包,可帮助您在开发工作流程中自动执行痛苦或耗时的任务。
- 与平台无关 - 集成被集成到所有主流IDE中,人们正在使用PHP,.NET,Node.js,Java和其他平台。
- 强大的生态系统 - 使用npm模块做任何你想要的,拥有超过2000个插件进行流文件转换。
- 简单 - 仅提供最少的API,易于学习和使用简单。用gulp对自己的描述就是:Automate and enhance your workflow。

安装

要使用gulp要保证你的电脑上要有node环境

官方建议你这么安装它

$ npm install gulp-cli -g
$ npm install gulp -D
$ touch gulpfile.js
$ gulp --help

更新

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

API

gulp4在gulp3的基础上新增了几个函数,但它的使用依旧简单方便。一共如下10个:

- gulp.src() --全局匹配一个或多个文件
- gulp.dest() --将文件写入目录
- gulp.symlink() --与dest相似,但是使用软连接形式
- gulp.task() --定义任务
- gulp.lastRun() --获得上次成功运行的时间戳
- gulp.parallel() --并行运行任务
- gulp.series() --运行任务序列
- gulp.watch() --当文件发生变化时做某些操作
- gulp.tree() --获得任务书树
- gulp.registry() --获得或注册任务

官方说明API说明:https://github.com/gulpjs/gulp/blob/master/docs/API.md

task(parallel and series)

gulp不再能够通过数组形式传入任务,再gulp4中你需要使用gulp.series()和gulp.parallel()来执行他们。例如:

gulp.task('default',gulp.parallel('taskA','taskB'));//并行执行
gulp.task('default',gulp.series('taskA','taskB'));//按顺序执行

parallel和series函数可以接受函数作为参数,这意味着我们可以将任务用独立函数表示:

funcion taskA(){...}
funcion taskB(){...}

gulp.task(taskA);//最简单的方式
gulp.task('i-am-taskB',taskB);//为taskB添加任务名
gulp.task('taskA-taskB', gulp.series(taskA, taskB));//序列执行
gulp.task('taskA-taskB', gulp.parallel(taskA,taskB));//并行运行

而且当我们执行序列化任务时,面板的输出也更加清晰

PS D:\github\resume> gulp
[21:49:59] Using gulpfile D:\project\gulpfile.js
[21:49:59] Starting 'default'...
[21:49:59] Starting 'copyfile'...
[21:49:59] Finished 'copyfile' after 90 ms
[21:49:59] Starting 'minifyhtml'...
[21:49:59] Finished 'minifyhtml' after 171 ms
[21:49:59] Starting 'minifyCSS'...
[21:50:00] Finished 'minifyCSS' after 353 ms
[21:50:00] Starting 'uglyfyJS'...
[21:50:01] Finished 'uglyfyJS' after 1.43 s
[21:50:01] Finished 'default' after 2.05 s

gulp.task 移除了三参数语法,现在不能使用数组来指定一个任务的依赖。

gulp 4.0 加入了 gulp.series 和 gulp.parallel 来实现任务的串行化和并行化。 任务函数中,如果任务是同步的,需要使用 done 回调。这样做是为了让 gulp 知道你的任务何时完成。

类似这样:

gulp.task(‘a’, function(done){
    //sync task…
    done()
})

如果任务是异步的,有多个方法可以标记任务完成。

  1. 回调

gulp.task('clean', function(done) {
    del(‘app/*')
        .then(function() {
            done()
        })
        .catch(function(err) {
            throw err
        })
})
  1. 返回流(Stream) 通常可以通过返回 gulp.src 实现。一个 Stream 在完成或者发生错误后会调用 end of stream 模块,该模块会执行一个回调来标记是否完成。这里说的 Stream 仅包括 readable/writable/duplex stream 等真实流,因此类似 event-stream 的伪流是不被支持的。

  2. 返回 Promise 把异步任务包装成一个 Promise 并返回。Promise 在完成后调用 onFulfilled 方法来标记任务的完成。

  3. 返回子进程 子进程同样也会在完成后调用 end of stream 模块。

var spawn = require('child_process').spawn
gulp.task('clean', function() { 
    return spawn('rm', ['-rf', path.join(__dirname, 'build')])
});

事实上,所有符合 asyncDone API 的任务函数,都可以用于 gulp task 中。

  • gulp.dest 添加了 dirMode 参数,可以指定生成文件夹的模式。

  • gulp.src 的 glob 参数按顺序求值,例如 gulp.src([‘.js’, ‘!b.js’, ‘bad.js’]),会去掉 bad.js 外所有 b 开头的 js 文件。

  • gulp.src 添加 since 选项,只匹配在某个固定时间后有修改的文件,这可以用来做增量构建。

gulp.task('img', function images() {
    return gulp.src(Path.img.src, {since: gulp.lastRun('img')})
        .pipe(plumber())
        .pipe(imagemin([
            imagemin.gifsicle({interlaced: true}),
            imagemin.jpegtran({progressive: true}),
            imagemin.optipng({optimizationLevel: 1}),
            imagemin.svgo({
                plugins: [
                    {removeViewBox: true}
                ]
            })
        ]))
        .pipe(gulp.dest(Path[env]))
})
  • gulp.dest 添加 overwrite 选项,用来控制是否覆盖已存在的文件。

  • gulp.task 就是一个普通函数,因此在 gulp 4.0 中,我们不必把每个 task 函数 都加到 gulp.task 的回调中。

gulp.task('local', gulp.series(clean, gulp.parallel(php, js), watch))

function clean() {
    return spawn('rm', ['-rf', Path[env]])
}

function php() {
    return gulp.src(Path.php.src, {since: gulp.lastRun(php)})
        .pipe(plumber())
        .pipe(gulp.dest(Path[env]))
        .pipe(livereload())
}

function js() {
    return gulp.src(Path.js.src, {since: gulp.lastRun(js)})
        .pipe(plumber())
        .pipe(gulp.dest(Path[env]))
        .pipe(livereload())
}

function watch(done) {
    livereload.listen()
    gulp.watch('app/php/**/*.php', gulp.series(php))
    gulp.watch('app/js/**/*.js',  gulp.series(js))
    done()
}

利用 js 函数的提升特性,我们可以在文件开头定义 task。而在 gulp 3.0,主 task 必须在所有子 task 定义完成后才能定义。另外,这里的 clean, php 等任务实际上变成了私有的了。

赞(0) 打赏
未经允许不得转载:徐礼文的技术博客 » gulp 4.0 升级指南
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏