简介

gulp 是前端自动化打包构建工具,所谓打包可以理解为把文件压缩, 整合, 移动, 混淆。gulp 是一种基于流的打包构建工具。

文档:https://www.gulpjs.com.cn/docs/api/concepts/

使用 gulp,首先要全局安装gulp,全局安装只是可以使用其命令

1
2
3
4
5
6
# 安装
npm install --global gulp
# 卸载
npm uninstall --global gulp
# 查看版本
gulp -v

也可以局部安装,通过scripts运行。

常用 API

  1. task()

    创建一个基于流的任务

    1
    2
    3
    gulp.task('htmlHandler', function () {
    // 找到 html 源文件, 进行压缩, 打包, 放入指定目录
    })
  2. src()

    找到源文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    // 找到指定一个文件
    gulp.src('./a/b.html')

    // 找到指定目录下, 指定后缀的文件
    gulp.src('./a/*.html')

    // 找到指令目录下的所有文件
    gulp.src('./a/**')

    // 找到 a 目录下所有子目录里面的所有文件
    gulp.src('./a/** /*')

    // 找到 a 目录下所有子目录里面的所有 .html 文件
    gulp.src('./a/** /*.html')
  3. dest()

    把一个内容放入指定目录内

    1
    gulp.dest('./abc')
  4. watch()

    监控指定目录下的文件, 一旦发生变化, 从新执行后面的任务

    1
    gulp.watch('./src/pages/*.html', htmlHandler)
  5. series()

    逐个执行多个任务, 前一个任务结束, 第二个任务开始

    1
    gulp.series(任务1, 任务2, 任务3, ...)
  6. parallel()

    并行开始多个任务

    1
    gulp.parallel(任务1, 任务2, 任务3, ...)
  7. pipe()

    管道函数,所有的 gulp API 都是基于流。接收当前流, 进入下一个流过程的管道函数

    1
    gulp.src().pipe(压缩任务).pipe(转码).pipe(gulp.dest('abc'))

常用插件

  1. gulp-cssmin

    1
    npm i gulp-cssmin -D

    导入以后得到一个处理流文件的函数

    https://www.npmjs.com/package/gulp-cssmin

  2. gulp-autoprefixer

    1
    npm i gulp-autoprefixer -D

    导入以后得到一个处理流文件的函数,直接再管道函数里面使用, 需要传递参数

    1
    2
    3
    {
    browsers: [要兼容的浏览器]
    }

    https://www.npmjs.com/package/gulp-autoprefixer

  3. gulp-sass

    编译scsssass文件为css文件

    1
    npm i gulp-sass -D

    导入后直接使用即可

  4. gulp-less

    gulp-sass类似,编译less文件为css文件

  5. gulp-uglify

    压缩js文件

    1
    npm i -D gulp-uglify

    此压缩不可以压缩ES6,因此如果有 ES6 代码,需要先转为ES5

  6. gulp-babel

    专门进行 ES6 转 ES5 的插件。

    1
    yarn add gulp-babel @babel/core  @babel/preset-env -D

    gulp-babel 有两个版本,8 主要用于 gulp4 中,7 主要用于 gulp3 中。默认安装最新版。

  7. gulp-htmlmin

    压缩 html

    1
    npm i -D gulp-htmlmin
  8. del

    删除文件目录

    1
    yarn add del -D
  9. gulp-connect

    启动一个服务器,用于自动构建。

    1
    yarn add gulp-connect -D
  10. gulp-pug

    编译pughtml文件

    1
    yarn add gulp-pug -D
  11. gulp-concat

    合并js/css文件

    1
    yarn add gulp-concat -D

常用示例

构建 JS

将含有 ES6 代码的 js 文件合并并压缩。

安装插件

1
yarn add gulp-concat gulp-uglify gulp-rename gulp-babel @babel/core  @babel/preset-env -D

编写构建任务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var gulp = require('gulp')
var concat = require('gulp-concat')
var uglify = require('gulp-uglify')
var rename = require('gulp-rename')
var babel = require('gulp-babel')

const js = () => {
return (
gulp
.src('src/js/*.js')
// .pipe(concat('build.js')) // 参数为合并完的文件名
.pipe(
babel({
presets: ['@babel/env']
})
)
// .pipe(gulp.dest('dist/js/')) // 临时输出文件到本地
.pipe(uglify()) // 压缩文件
// .pipe(rename({ suffix: '.min' })) // 重命名
.pipe(gulp.dest('dist/js/')) // 输出文件
)
}

exports.default = gulp.parallel(js)

css、less、scss、sass

安装插件

1
yarn add gulp-less gulp-sass gulp-clean-css gulp-concat del gulp-rename  -D

编写任务代码

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
// 编译scss
const scssTask = () => {
return gulp
.src('./src/scss/*.scss')
.pipe(sass())
.pipe(gulp.dest('./src/css/scss/'))
}
// 编译less
const lessTask = () => {
return gulp
.src('./src/less/*.less')
.pipe(less())
.pipe(gulp.dest('./src/css/less/'))
}
// 删除 less 和 scss 产生的文件夹
const delLessScss = () => {
return del(['./src/css/less/', './src/css/scss/'])
}
// 处理css文件
const cssTask = async () => {
return gulp
.src('./src/css/**/*.css')
.pipe(concat('build.css'))
.pipe(rename({ suffix: '.min' }))
.pipe(cssClean({ compatibility: 'ie8' }))
.pipe(gulp.dest('dist/css/'))
}

exports.default = gulp.series(
gulp.parallel(scssTask, lessTask),
cssTask,
delLessScss
)

编译 pug、压缩 html

安装插件

1
yarn add gulp-htmlmin gulp-pug del -D

编写压缩任务

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
// 删除dist目录
const delDest = () => {
return del(['./dist/'])
}

// 编译pug任务
const pugTask = () => {
return gulp.src('./src/pug/*.pug').pipe(pug()).pipe(gulp.dest('./dist/'))
}
// 压缩html
const htmlminTask = () => {
return gulp.src('./dist/**/*.html').pipe(
htmlmin({
removeComments: true, //清除HTML注释
collapseWhitespace: true, //压缩HTML
collapseBooleanAttributes: true, //省略布尔属性的值 <input checked="true"/> ==> <input checked />
removeEmptyAttributes: true, //删除所有空格作属性值 <input id="" /> ==> <input />
removeScriptTypeAttributes: true, //删除<script>的type="text/javascript"
removeStyleLinkTypeAttributes: true, //删除<style>和<link>的type="text/css"
minifyJS: true, //压缩页面JS
minifyCSS: true //压缩页面CSS
})
)
}

exports.default = gulp.series(delDest, pugTask, htmlminTask)

自动化示例

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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/**
* @description:
* @author: 小康
* @url: https://xiaokang.me
* @Date: 2020-12-26 17:11:49
* @LastEditTime: 2020-12-26 17:11:49
* @LastEditors: 小康
*/
var gulp = require('gulp')

var pug = require('gulp-pug')
var htmlmin = require('gulp-htmlmin')
var less = require('gulp-less')
var sass = require('gulp-sass')
var cssClean = require('gulp-clean-css')

var uglify = require('gulp-uglify')
var babel = require('gulp-babel')

var concat = require('gulp-concat')
var rename = require('gulp-rename')
var del = require('del')

var connect = require('gulp-connect')
var open = require('open')
// 删除dist目录
const delDest = () => {
return del(['./dist/'])
}
// 删除 less 和 scss 产生的文件夹
const delLessScss = () => {
return del(['./src/css/less/', './src/css/scss/'])
}

// 编译pug任务
const pugTask = () => {
return gulp
.src('./src/pug/*.pug')
.pipe(pug())
.pipe(gulp.dest('./dist/'))
.pipe(connect.reload())
}
// 压缩html
const htmlminTask = () => {
return gulp
.src('./dist/**/*.html')
.pipe(
htmlmin({
removeComments: true, //清除HTML注释
collapseWhitespace: true, //压缩HTML
collapseBooleanAttributes: true, //省略布尔属性的值 <input checked="true"/> ==> <input checked />
removeEmptyAttributes: true, //删除所有空格作属性值 <input id="" /> ==> <input />
removeScriptTypeAttributes: true, //删除<script>的type="text/javascript"
removeStyleLinkTypeAttributes: true, //删除<style>和<link>的type="text/css"
minifyJS: true, //压缩页面JS
minifyCSS: true //压缩页面CSS
})
)
.pipe(connect.reload())
}

// 编译scss
const scssTask = () => {
return gulp
.src('./src/scss/*.scss')
.pipe(sass())
.pipe(gulp.dest('./src/css/scss/'))
.pipe(connect.reload())
}
// 编译less
const lessTask = () => {
return gulp
.src('./src/less/*.less')
.pipe(less())
.pipe(gulp.dest('./src/css/less/'))
.pipe(connect.reload())
}

// 处理css文件
const cssTask = async () => {
return gulp
.src('./src/css/**/*.css')
.pipe(concat('build.css'))
.pipe(rename({ suffix: '.min' }))
.pipe(cssClean({ compatibility: 'ie8' }))
.pipe(gulp.dest('dist/css/'))
.pipe(connect.reload())
}

// 编译js
const jsTask = () => {
return gulp
.src('src/js/*.js')
.pipe(
babel({
presets: ['@babel/env']
})
)
.pipe(uglify()) // 压缩文件
.pipe(gulp.dest('dist/js/')) // 输出文件
.pipe(connect.reload())
}
const server = () => {
gulp.watch(['src/scss/**/*.scss'], gulp.series(scssTask))
gulp.watch(['src/less/**/*.less'], gulp.series(lessTask))
gulp.watch(['src/css/**/*.css'], gulp.series(cssTask))
gulp.watch(['src/pug/**/*.pug'], gulp.series(pugTask))
gulp.watch(['src/js/**/*.js'], gulp.series(jsTask))
connect.server({
root: 'dist/',
livereload: true,
port: 5000
})
open('http://localhost:5000/')
}

gulp.task(
'build',
gulp.series(
delDest,
pugTask,
htmlminTask,
scssTask,
lessTask,
cssTask,
jsTask,
delLessScss
)
)
gulp.task('server', gulp.series('build', server))

关于任务执行顺序

同步执行即按顺序执行

1
exports.default = gulp.series('js', ['less', 'css'])

异步执行即不会按照顺序去执行

1
exports.default = gulp.parallel('js', ['less', 'css'])

这两个方法支持任意层次的嵌套。

1
exports.default = gulp.parallel('js', gulp.series(['less', 'css']))