目录
- Glup
- Gulp的使用步骤
- Gulp的基本使用
- 安装
- 起步
- 默认任务
- gulp4.0之前的任务注册
- Gulp的组合任务
- Gulp的异步任务
- 回调方式去解决
- stream
- Gulp构建过程核心工作原理
- Gulp读取流和写入流的API
之前写过一个4.0之前版本的gulp,这里引用一下 Gulp(4.0之前旧版本)——自动化的流程构建工具 ,不过可以不用看,直接看下面的就行。
Glup
特点就是高效、易用。使用Gulp
开发很简单。
Gulp的使用步骤
- 在项目中安装一个
Gulp
的开发依赖 - 在根目录下添加一个
gulpfile.js
文件,用于编写一些需要Gulp
自动构建的一些任务 - 在命令行中通过
cli
去运行这些任务
Gulp的基本使用
安装
npm i gulp
起步
- 创建一个
gulpfile.js
的文件,这是个gulp
的入口文件 - 在文件中创建任务
PS: 在最新的
gulp
中,取消了同步代码模式,约定每一个任务都是异步任务,当任务完成过后要标记任务完成。否则会报错
// gulpfile.js
exports.foo = () => {
console.log("foo task working~")
}
// 运行的时候虽然正常输出但是会报错,是否忘记添加结束?
// Starting 'foo'...
// foo task working~
// The following tasks did not complete: foo
// Did you forget to signal async completion?
添加参数done
表示任务结束
// gulpfile.js
exports.foo = done => {
console.log("foo task working~")
done() // 标识任务完成
}
- 命令行运行
gulp foo
# Using gulpfile E:\professer\Gulp\gulpfile.js
# Starting 'foo'...
# foo task working~
# Finished 'foo' after 2.43 ms
默认任务
exports.default = done => {
console.log("default task working~")
done()
}
运行的时候不需要指定任务
gulp
# Using gulpfile E:\professer\Gulp\gulpfile.js
# Starting 'default'...
# default task working~
# Finished 'default' after 3.03 ms
gulp4.0之前的任务注册
在gulp4.0
以前,我们注册任务需要在gulp
模块的一个方法中实现
const gulp = require("gulp")
gulp.task('bar', done => {
console.log('bar working~')
done()
})
虽然4.0
之后还可以使用,但是这种方式已经不被推荐了。更推荐大家使用导出函数成员的方式去定义gulp
任务。
Gulp的组合任务
gulp
模块中的series, parallel
的API
可以轻松创建组合任务分别执行串行任务和并行任务。
// 引入串行并行方法
const {series, parallel} = require("gulp")
// 组合任务
const task1 = done => {
setTimeout(() => {
console.log("task1 working!")
done()
}, 1000)
}
const task2 = done => {
setTimeout(() => {
console.log("task2 working!")
done()
}, 1000)
}
const task3 = done => {
setTimeout(() => {
console.log("task3 working!")
done()
}, 1000)
}
// 串行的任务结构
// 接收任意个数的参数,每一个参数都是一个任务,按照顺序依次执行
exports.hello1 = series(task1, task2, task3)
// 并行的任务结构
exports.hello2 = parallel(task1, task2, task3)
命令行运行
gulp hello1
# 可以看到先执行了task1结束后才执行task2,task2结束后才执行task3
# Using gulpfile E:\professer\Gulp\gulpfile.js
# Starting 'task1'...
# task1 working!
# Finished 'task1' after 1.01 s
# Starting 'task2'...
# task2 working!
# Finished 'task2' after 1 s
# Starting 'task3'...
# task3 working!
# Finished 'task3' after 1.01 s
# Finished 'hello1' after 3.08 s
gulp hello2
# 可以看到task1,task2,task3同时开始执行
# Using gulpfile E:\professer\Gulp\gulpfile.js
# Starting 'hello2'...
# Starting 'task1'...
# Starting 'task2'...
# Starting 'task3'...
# task1 working!
# Finished 'task1' after 1.01 s
# task2 working!
# Finished 'task2' after 1.02 s
# task3 working!
# Finished 'task3' after 1.02 s
# Finished 'hello2' after 1.02 s
用途
- 例如部署项目,先需要执行编译任务,就需要串行任务。
- 例如
css
和js
的编译和压缩,彼此互不干扰,就可以使用并行任务。
Gulp的异步任务
回调方式去解决
1. 普通回调
exports.callback = done => {
console.log("callback task~")
done()
}
这种回调方式和node
的是一种,都是错误优先的方式,如果我们要返回一种错误的回调,需要在done
中传参数
exports.callback_error = done => {
console.log("callback error task~")
done(new Error('task failed~'))
}
这个时候运行观察会报出错误,而且之后的任务都不会再继续执行。
gulp callback_error
# Using gulpfile E:\professer\Gulp\gulpfile.js
# Starting 'callback_error'...
# callback error task~
# 'callback_error' errored after 2.38 ms
# Error: task failed~
# at exports.callback_error (E:\professer\Gulp\gulpfile.js:51:8)
# at callback_error (E:\professer\Gulp\node_modules\undertaker\lib\set-task.js:13:15)
# at bound (domain.js:427:14)
# at runBound (domain.js:440:12)
# at asyncRunner (E:\professer\Gulp\node_modules\async-done\index.js:55:18)
# at processTicksAndRejections (internal/process/task_queues.js:79:11)
2. promise
gulp
任务还支持接受promise
exports.promise = () => {
console.log("promise task~")
// 这里通过promise的resolve方法返回一个成功的promise
// 一旦resolve了,那么任务就结束了
// resolve里面不需要传参数,因为gulp会忽略这个值
return Promise.resolve()
}
promise
失败怎么办?reject
方法就可以
exports.promise_error = () => {
console.log("promise task~")
return Promise.reject(new Error('promise failed'))
}
3. async/await
ES7
中的async
和await
也可以
PS:如果
node
版本是8+
就可以使用这种方式
const delay = time => {
return new Promise((resolve, reject) => {
setTimeout(resolve, time)
})
}
exports.async = async () => {
await delay(1000)
console.log("async task~")
}
执行
gulp async
# Using gulpfile E:\professer\Gulp\gulpfile.js
# Starting 'async'...
# async task~
# Finished 'async' after 1.01 s
stream
需要在任务函数中返回一个stream
对象
const fs = require("fs")
exports.stream = () => {
// 读取文件的文件流对象
const readStream = fs.createReadStream('package.json')
// 写入文件的文件流对象
const writeStream = fs.createWriteStream('temp.txt')
// 文件复制从读入通过管道倒入到写入里面
readStream.pipe(writeStream)
// 把readStream返回
return readStream
}
整个任务完成的时机就是stream
对象end
的时候。因为stream
对象都有一个end
事件,文件流读取完成过后,end
事件就会执行。gulp
就会知道任务已经完成了。
类似于
exports.end = done => {
const readStream = fs.createReadStream('package.json')
const writeStream = fs.createWriteStream('temp.txt')
readStream.pipe(writeStream)
// 监听了end事件执行done
readStream.on('end', () => {
done()
})
}
Gulp构建过程核心工作原理
Gulp
是一个基于流的构建系统。
工作原理 就是把文件读取出来,做完操作之后写入到另一个文件中。
const fs = require("fs")
const { Transform } = require('stream')
exports.default = () => {
// 文件读取流
const read = fs.createReadStream('normalize.css')
// 文件写入流
const write = fs.createWriteStream('normalize.min.css')
// 文件转换流
const transform = new Transform({
transform: (chunk, encoding, callback) => {
// ★★★核心转换过程实现★★★
// chunk => 读取流中读取到的内容(Buffer)
// 使用toString将Buffer数组转化成字符串
const input = chunk.toString()
// 替换掉空白字符和css注释
// 将转换后的结果放在output变量中
const output = input.replace(/\s+/g, '').replace(/\/\*.+?\*\//g, '')
// 执行callback的时候返回,错误优先第一个传错误参数,没有的话传null
// output是成功之后作为结果导出
callback(null, output)
}
})
// 文件复制从读入通过管道先转换,后倒入到写入里面
read
.pipe(transform)
.pipe(write)
return read
}
Gulp读取流和写入流的API
Gulp
中专门提供了读取流和写入流的API
,比node
的API
更加强大,更容易使用。转换流大都是通过独立的插件来提供。
举个栗子:
- 加载一个压缩css的插件
npm install gulp-clean-css
和修改文件类型的插件npm install gulp-rename
- 在
gulpfile.js
里面写
const { src, dest} = require('gulp')
const cleanCss = require('gulp-clean-css')
const rename = require('gulp-rename')
exports.default = done => {
// 读取流,参数是文件路径,比较强大的地方是这里可以使用通配符匹配多个文件
src('src/*.css')
// 压缩代码
.pipe(cleanCss())
// 修改文件类型
.pipe(rename({ extname: '.min.css'}))
// 输出流,参数是输出路径
.pipe(dest('dest'))
done()
}
- 在命令行中运行
gulp
可以看到对应的文件生成,是压缩过的且名称变成了normalize.min.css
。
网友评论