初探 gulp

初探 gulp

七月 07, 2021 本文共计: 823 字 预计阅读时长: 3分钟

上一篇文章中我们有提到UMDCJSAMDESM的区别,今天这篇呢,就打包代码,抛砖引玉,我们来探索下gulp

gulp比较清晰深刻的两个概念就是流(Stream)任务(Task)

以函数式编程的形式,一个函数一个Task,去执行任务,Task之间的数据传输是以Stream的形式去流动的,最终输出到指定目录。

快速开始Hello World,参考传送门

名词一:任务

任务分为共有任务私有任务

提前声明的是:

gulp 不再支持同步任务(Synchronous tasks)

gulp 不再支持同步任务(Synchronous tasks)了。因为同步任务常常会导致难以调试的细微错误,例如忘记从任务(task)中返回 stream。
当你看到 “Did you forget to signal async completion?” 警告时,说明你并未使用前面提到的返回方式。你需要使用 callback 或返回 stream、promise、event emitter、child process、observable 来解决此问题。

那就意味着,我们的任务函数需要这么去编写:

1
2
3
4
5

async function myFirstGulpTask() {
// todo some
}

建立私有任务

1
2
3
4
5
6
7

async function privateTask() {

}

exports.build = privateTask

Note: 需要注意的点是,私有任务不能被外部使用者直接调用,例如:

1
$ gulp 

建立公有任务

1
2
3
4
5
6
7

async function publicTask() {

}

exports.default = publicTask

其实,不难猜测的是,对于一连串的任务,肯定是有一定的顺序的,但是也会有并行执行的场景:

那么这个时候seriesparallel就闪亮登场了。

其中,series控制顺序执行,parallel控制并发执行。

二者可以随意判断且嵌套使用,诸如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

// 判断

async function devTask() {

}

async function proTask() {

}

if (process.ENV === 'prod') {
exports.build = proTask
} else {
exports.build = devTask
}

// 嵌套
exports.default = series(devTask, proTask)
exports.default = parallel(devTask, proTask)

// OR

exports.default = parallel(devTask, series(proTask))

exports.default = series(devTask, parallel(proTask))

说到这里,你肯定会有些疑问,异步方案的替代品是否存在?

  1. 回归原始,回调控制执行时机
1
2
3
function task(cb) {
cb()
}

任务的执行机制如何?

当从任务(task)中返回 stream、promise、event emitter、child process 或 observable 时,成功或错误值将通知 gulp 是否继续执行或结束。如果任务(task)出错,gulp 将立即结束执行并显示该错误。

当使用 series() 组合多个任务(task)时,任何一个任务(task)的错误将导致整个任务组合结束,并且不会进一步执行其他任务。当使用 parallel() 组合多个任务(task)时,一个任务的错误将结束整个任务组合的结束,但是其他并行的任务(task)可能会执行完,也可能没有执行完。

任务执行

总结三点:读取(输入) –> 处理传输 –> 写入(输出)

以一个demo入手:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// gulpfile.js

const { src, dest, series } = require('gulp');
const ts = require('gulp-typescript');
const babel = require('gulp-babel')


async function cjs() {

const tsProject = ts.createProject('tsconfig.json', {
module: 'CommonJS',
});

return tsProject.src()
.pipe(tsProject())
.pipe(babel())
.pipe(dest('cjs/'))
}

async function esm() {
const tsProject = ts.createProject('tsconfig.json', {
module: 'ESNEXT',
});

return tsProject.src()
.pipe(tsProject())
.pipe(dest('es/'))
}

exports.default = series(cjs, esm)


到此,gulp初步探索就结束了,下篇将探索gulp高级玩法,诸如,结合 rollup、结合webpack……