官网看这里

Gulp:基于流的构建系统

安装

1
2
3
4
# 安装gulp命令行工具
yarn --global gulp-cli=
# 项目局部安装,开发依赖
yarn add gulp --dev

使用

在根目录下,创建gulpfile.js

基本使用

通过导出函数成员的方式定义任务。

gulp中的任务是异步任务,需要使用回调函数标记执行结束

gulpfile.js是gulp的执行文件,在gulpfile.js中添加构建指令。

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
//导出默认任务
exports.default = (done)=>{
console.log('default task')
//标示任务执行结束
done()
}

// 导出test任务
exports.test = (done)=>{
console.log('test task')
//标示任务执行结束
done()
}

//支持使用promise
exports.promise = ()=>{
console.log('promise task')
//Promise.resolve() 标示任务执行结束
return Promise.resolve()
}

//node 环境大于8时,可以使用async/await
exports.async = async()=>{
await new Promise(resolve=>{
setTimeout(resolve,1000)
})
console.log('async task')
}

执行gulp,会自动运行gulpfile.js中的default任务

gulp

运行gulp test会执行test任务

gulp

注意:对于异步执行函数,任务完成标记需要在回调函数中执行

1
2
3
4
5
6
exports.task = (done)=>{
setTimeout(()=>{
console.log("task")
done()
},1000)
}

组合任务

通过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
const {series, parallel}  = require('gulp')
const task1 = (done)=>{
setTimeout(()=>{
console.log("task1")
done()
},1000)
}
const task2 = (done)=>{
setTimeout(()=>{
console.log("task2")
done()
},1000)
}

const task3 = (done)=>{
setTimeout(()=>{
console.log("task3")
done()
},1000)
}
exports.seriesTask = series(task1,task2,task3)
exports.parallelTask = parallel(task1,task2,task3)

执行gulp seriesTask,任务串行执行

gulp-series

执行gulp parallelTask,任务并行执行

gulp-parallel

错误处理

因为gulp任务回调函数式错误优先,所有处理任务执行错误,仅需在done回调函数中传入错误信息即可。

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
33
34
35
36
37
38
39
40
41
const {series, parallel}  = require('gulp')
const task1 = (done)=>{
setTimeout(()=>{
console.log("task1")
done()
},1000)
}
const task2 = (done)=>{
setTimeout(()=>{
console.log("task2")
done()
},1000)
}

const task3 = (done)=>{
setTimeout(()=>{
console.log("task3")
done()
},1000)
}

// 导出test任务
const callback_error = (done)=>{
console.log('callback_error task')
//标示任务执行结束
done(new Error("callback_error task failed"))
}

//同样支持Promise.reject
const promise_error = ()=>{
console.log('promise error task')
//Promise.reject() 标示任务执行失败
return Promise.reject(new Error("promise_error task failed"))
}

const parallelTask = parallel(task1,callback_error,task2,task3)

module.exports = {
callback_error,
parallelTask
}

执行callback_error,报错

gulp-error

执行组合函数,遇到错误任务时,会停止执行后续任务

gulp-parallel

流的方式使用gulp

使用文件流实现文件复制

1
2
3
4
5
6
7
8
9
10
11
const fs = require('fs')
exports.stream = ()=>{
//读取文件流
const readStream = fs.createReadStream('package.json')
//写入文件流
const writeStream = fs.createWriteStream('temp.txt')
//通过pipe()将读取文件流导入写入文件流
readStream.pipe(writeStream)
//readStream end的时候即为任务结束的时机
return readStream
}

gulp-stream

gulp构建过程核心工作原理

读取文件,加工文件,写入另外一个位置

例子,实现css的压缩

使用fs模块读取和写入文件流。

使用steramTransform实现文件内部的修改

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
const fs = require('fs')
const {Transform} = require('stream')

exports.default = ()=>{
//读取文件流
const readFile = fs.createReadStream('normalize.css')
//写入文件流
const writeFile = fs.createWriteStream('notmalize.min.css')

//处理文件流
const transform = new Transform({
transform:(chunk,encoding,callback)=>{
//核心转换过程
//chunk:读取文件流中读取到的内容(Buffer)
const input = chunk.toString()
//替换或有的空格与css注释
const output = input.replace(/\s+/g,"").replace(/\/\*.+?\*\//g,"")
callback(null,output)
}
})

//把读取的文件流导入写入文件流
readFile
.pipe(transform) // 先将读取文件流进行转换
.pipe(writeFile) // 将转换结果导入到写入文件流
return readFile
}

normalize.css

1
2
3
4
/* 这是body注释 */
body{
background-color: #cccccc;
}

执行gulp

转换后的 normalize.min.css

1
body{background-color:#cccccc;}

文件操作API

使用gulp的src 模块实现文件流读取,dest实现文件流写入

1
2
3
4
5
6
7
8
9
10
11
12
const { src, dest }  = require('gulp')

exports.default = ()=>{
return src('src/normalize.css')
.pipe(dest('dist'))
}

//可以使用通配符匹配所有文件
exports.css = ()=>{
return src('src/s*.css')
.pipe(dest('dist'))
}

常用插件

  1. gulp-clean-css 压缩css文件

    1
    2
    3
    4
    5
    6
    7
    8
    const { src, dest }  = require('gulp')
    const cleanCss = require('gulp-clean-css')

    exports.default = ()=>{
    return src('src/normalize.css')
    .pipe(cleanCss()) // 先进行转换
    .pipe(dest('dist'))
    }
  2. gulp-rename重命名文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    const { src, dest }  = require('gulp')
    const cleanCss = require('gulp-clean-css')
    const rename = require('gulp-rename')

    exports.default = ()=>{
    return src('src/normalize.css')
    .pipe(cleanCss()) // 先进行转换
    .pipe(rename({extname:".min.css",}))
    .pipe(dest('dist'))
    }
  3. gulp-sass用于构建scss文件为css`文件

    gulp-sass会默认认为_开头的scss文件为依赖样式,不会导出css文件

    1
    2
    3
    4
    5
    6
    7
    const { src, dest }  = require('gulp')
    const sass = require('gulp-sass')
    exports.default = ()=>{
    return src('src/assets/scss/*.scss',{base:'src'})
    .pipe(sass()) // 进行转换
    .pipe(dest('dist'))
    }
  4. gulp-babel用于构建脚本文件,实现es6的向下转换

    使用gulp-babel不会自动安装babel/core核心模块,还需要手动安装@babel/core以及@babel/preset-env

    @babel/preset-env会默认将ES6的所有新特性进行转换

    1
    2
    3
    4
    5
    6
    7
    8
    9
    const { src, dest } = require('gulp')
    const babel = require('gulp-babel')

    //实现脚本文件编译
    exports.default = () =>{
    return src('src/assets/scripts/*.js', { base: "src/" })
    .pipe(babel({presets:['@babel/preset-env']}))//指定转换preset
    .pipe(dest('dist'))
    }
  5. gulp-imagemin用于图片压缩

    gulp-imagemin是图片无损压缩,只是删除了图片的一些附属信息。

    1
    2
    3
    4
    5
    6
    7
       const { src, dest } = require('gulp')
    const imagemin = require('gulp-imagemin')
    exports.default = ()=>{
    return src('src/assets/images/*', { base: "src/" })
    .pipe(imagemin())//压缩图片
    .pipe(dest('dist'))
    }
  1. gulp-load-plugins用于管理plugin,能够自动加载所有的plugin

    1
    yarn add gulp-load-plugins --dev
    1
    2
    3
    4
    5
    6
    7
    8
    9
    const loadPlugins = require('gulp-load-plugins')
    const plugins = loadPlugins()
    //通过`plugin.`的方式调用模块
    const { src, dest, parallel,series} = require('gulp')
    exports.default = ()=>{
    return src('src/assets/images/*', { base: "src/" })
    .pipe(plugins.imagemin())//通过`plugin.imagemin`的方式调用图片压缩模块
    .pipe(dest('dist'))
    }

其他模块

  1. del模块可以实现文件夹清空

    1
    yarn add del --dev
    1
    2
    3
    4
    5
    6
    7
    8
    9
    const del = require('del')

    const clean = ()=>{
    return del(['dist'])
    }

    module.exports={
    clean
    }
  2. browser-sync服务器,模块提供开发服务器,实现热更新

    看这里

构建实例

移步这里