# 1.什么是 gulp
- gulp 是可以自动化执行任务的工具 在平时开发的流程里面,一定有一些任务需要手工重复得执行,比如:
- 把文件从开发目录拷贝到生产目录
- 把多个 JS 或者 CSS 文件合并成一个文件
- 对 JS 文件和 CSS 进行压缩
- 把 sass 或者 less 文件编译成 CSS
- 压缩图像文件
- 创建一个可以实时刷新页面内容的本地服务器
- 只要你觉得有些动作是要重复去做的,就可以把这些动作创建成一个 gulp 任务,然后在指定的条件下自动执行
# 2. gulp 特点
- 易于使用 通过代码优于配置的策略,Gulp 让简单的任务简单,复杂的任务可管理
- 快速构建 利用 node.js 流的威力,你可以快速构建项目并减少频繁的 IO 操作
- 高质量的插件 Gulp 严格的插件指南确保插件如你期望的那样简洁地工作
- 易于学习 通过最少的 API,掌握 gulp 毫不费力,构建工作尽在掌握
# 3. 安装 gulp
npm install --g gulp-cli
npm install --save-dev gulp
1
2
2
# 4. 异步任务和组合任务
gulpfile.js
const fs = require("fs")
const through = require("through2")
const { series, parallel } = require("gulp")
function callbackTask(done) {
setTimeout(() => {
console.log("callbackTask")
done()
}, 1000)
}
function promiseTask() {
return new Promise((resolve) => {
setTimeout(() => {
console.log("promiseTask")
resolve()
}, 1000)
})
}
async function asyncTask() {
await new Promise((resolve) => {
setTimeout(() => {
resolve()
}, 1000)
})
console.log("asyncTask")
}
function streamTask() {
return fs
.createReadStream("input.txt")
.pipe(
through((chunk, encoding, next) => {
setTimeout(() => {
next(null, chunk)
}, 1000)
})
)
.pipe(fs.createWriteStream("output.txt"))
}
const parallelTask = parallel(callbackTask, promiseTask, asyncTask, streamTask)
const seriesTask = series(callbackTask, promiseTask, asyncTask, streamTask)
exports.callback = callbackTask
exports.promise = promiseTask
exports.async = asyncTask
exports.stream = streamTask
exports.parallel = parallelTask
exports.series = seriesTask
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
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
# 5. gulp 核心 API
# 5.1 gulp.src()
- gulp.src()方法正是用来获取流的
- 注意这个流里的内容不是原始的文件流,而是一个虚拟文件对象流
- globs 参数是文件匹配模式(类似正则表达式),用来匹配文件路径(包括文件名),当然这里也可以直接指定某个具体的文件路径。当有多个匹配模式时,该参数可以为一个数组
- options 为可选参数
- gulp.src(globs[, options])
# 5.2 gulp.dest()
- gulp.dest()是用来向硬盘写入文件的
- path 为写入文件的路径
- options 为一个可选的参数对象
- gulp.dest()传入的路径参数只能用来指定要生成的文件的目录,而不能指定生成文件的文件名 它生成文件的文件名使用的是导入到它的文件流自身的文件名 所以生成的文件名是由导入到它的文件流决定的
- gulp.dest(path)生成的文件路径是我们传入的 path 参数后面再加上 gulp.src()中有通配符开始出现的那部分路径
- 通过指定 gulp.src()方法配置参数中的 base 属性,我们可以更灵活的来改变 gulp.dest()生成的文件路径
- gulp.dest(path[,options])
# 5.3 pipe
gulpfile.js
const { src, dest } = require('gulp');
function copyTask() {
console.log('执行拷贝任务');
return src('src/**/*.js').pipe(dest('dist'));
}
exports.default = copyTask;
1
2
3
4
5
6
2
3
4
5
6
# 6. gulp 实战
# 6.1 安装
cnpm install @babel/core @babel/preset-env browser-sync gulp gulp-babel gulp-clean gulp-clean-css gulp-ejs gulp-htmlmin gulp-if gulp-imagemin gulp-less gulp-load-plugins gulp-uglify gulp-useref gulp-watch map-stream bootstrap jquery --save
1
# 6.2 编译样式
const { src, dest } = require("gulp")
const less = require("gulp-less")
const styles = () => {
return src("src/styles/*.less", { base: "src" })
.pipe(less())
.pipe(dest("dist"))
}
exports.styles = styles
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 6.3 编译脚本
const { src, dest } = require('gulp');
const less = require('gulp-less');
const babel = require('gulp-babel');
const styles = () => {
return src("src/styles/*.less", { base: 'src' })
.pipe(less())
.pipe(dest('dist'))
}
+const scripts = () => {
+ return src("src/scripts/*.js", { base: 'src' })
+ .pipe(babel({
+ presets: ["@babel/preset-env"]
+ }))
+ .pipe(dest('dist'))
+}
exports.styles = styles;
+exports.scripts = scripts;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 6.4 编译 html
# 6.4.1 src\index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title><%=title%></title>
<link
rel="stylesheet"
href="node_modules/bootstrap/dist/css/bootstrap.css"
/>
<link rel="stylesheet" href="styles/main.css" />
</head>
<body>
<button class="btn btn-danger">按钮</button>
<img src="assets/images/circle.svg" />
<img src="rect.svg" />
<script src="node_modules/jquery/dist/jquery.js"></script>
<script src="scripts/main.js"></script>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 6.4.2 circle.svg
src\assets\images\circle.svg
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100" height="100" version="1.1" xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="50" r="50" fill="red"/>
</svg>
1
2
3
4
5
2
3
4
5
# 6.4.3 static\rect.svg
static\rect.svg
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100" height="100" version="1.1" xmlns="http://www.w3.org/2000/svg">
<rect width="100" height="100" style="fill:red;"/>
</svg>
1
2
3
4
5
2
3
4
5
# 6.4.4 gulpfile.js
const { src, dest, parallel } = require('gulp');
const less = require('gulp-less');
const babel = require('gulp-babel');
const ejs = require('gulp-ejs');
const styles = () => {
return src("src/styles/*.less", { base: 'src' })
.pipe(less())
.pipe(dest('dist'))
}
const scripts = () => {
return src("src/scripts/*.js", { base: 'src' })
.pipe(babel({
presets: ["@babel/preset-env"]
}))
.pipe(dest('dist'))
}
+const html = () => {
+ return src("src/*.html", { base: 'src' })
+ .pipe(ejs({ title: 'gulp' }))
+ .pipe(dest('dist'))
+}
exports.styles = styles;
exports.scripts = scripts;
+exports.html = html;
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
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
# 6.5 编译任务
const { src, dest, parallel } = require('gulp');
const less = require('gulp-less');
const babel = require('gulp-babel');
const ejs = require('gulp-ejs');
const styles = () => {
return src("src/styles/*.less", { base: 'src' })
.pipe(less())
.pipe(dest('dist'))
}
const scripts = () => {
return src("src/scripts/*.js", { base: 'src' })
.pipe(babel({
presets: ["@babel/preset-env"]
}))
.pipe(dest('dist'))
}
const html = () => {
return src("src/*.html", { base: 'src' })
.pipe(ejs({ title: 'gulp' }))
.pipe(dest('dist'))
}
+const compile = parallel(styles, scripts, html);
exports.styles = styles;
exports.scripts = scripts;
exports.html = html;
+exports.compile = compile;
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
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
# 6.6 压缩图片
# 6.6.1 安装
npm install gulp-imagemin --save-dev
npm install imagemin-jpegtran imagemin-svgo imagemin-gifsicle imagemin-optipng --save-dev
1
2
2
# 6.6.2 gulpfile.js
const { src, dest, parallel } = require('gulp');
const less = require('gulp-less');
const babel = require('gulp-babel');
const ejs = require('gulp-ejs');
const styles = () => {
return src("src/styles/*.less", { base: 'src' })
.pipe(less())
.pipe(dest('dist'))
}
const scripts = () => {
return src("src/scripts/*.js", { base: 'src' })
.pipe(babel({
presets: ["@babel/preset-env"]
}))
.pipe(dest('dist'))
}
const html = () => {
return src("src/*.html", { base: 'src' })
.pipe(ejs({ title: 'gulp' }))
.pipe(dest('dist'))
}
+const images = async () => {
+ let imagemin = await import('gulp-imagemin');
+ return src("src/assets/images/**/*.@(jpg|png|gif|svg)", { base: 'src' })
+ .pipe(imagemin.default())
+ .pipe(dest('dist'))
+}
const compile = parallel(styles, scripts, html);
exports.styles = styles;
exports.scripts = scripts;
exports.html = html;
exports.compile = compile;
+exports.images = images;
6.7 拷贝静态文件
const { src, dest, parallel } = require('gulp');
const less = require('gulp-less');
const babel = require('gulp-babel');
const ejs = require('gulp-ejs');
const styles = () => {
return src("src/styles/*.less", { base: 'src' })
.pipe(less())
.pipe(dest('dist'))
}
const scripts = () => {
return src("src/scripts/*.js", { base: 'src' })
.pipe(babel({
presets: ["@babel/preset-env"]
}))
.pipe(dest('dist'))
}
const html = () => {
return src("src/*.html", { base: 'src' })
.pipe(ejs({ title: 'gulp' }))
.pipe(dest('dist'))
}
const images = async () => {
let imagemin = await import('gulp-imagemin');
return src("src/assets/images/**/*.@(jpg|png|gif|svg)", { base: 'src' })
.pipe(imagemin.default())
.pipe(dest('dist'))
}
+const static = async () => {
+ return src("static/**", { base: 'static' })
+ .pipe(dest('dist'))
+}
const compile = parallel(styles, scripts, html);
+const build = parallel(compile, static)
exports.styles = styles;
exports.scripts = scripts;
exports.html = html;
exports.compile = compile;
exports.images = images;
+exports.static = static;
+exports.build = build;
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
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
# 6.8 删除输出目录
const { src, dest, parallel, series } = require('gulp');
const less = require('gulp-less');
const babel = require('gulp-babel');
const ejs = require('gulp-ejs');
+const gulpClean = require('gulp-clean');
const styles = () => {
return src("src/styles/*.less", { base: 'src' })
.pipe(less())
.pipe(dest('dist'))
}
const scripts = () => {
return src("src/scripts/*.js", { base: 'src' })
.pipe(babel({
presets: ["@babel/preset-env"]
}))
.pipe(dest('dist'))
}
const html = () => {
return src("src/*.html", { base: 'src' })
.pipe(ejs({ title: 'gulp' }))
.pipe(dest('dist'))
}
const images = async () => {
let imagemin = await import('gulp-imagemin');
return src("src/assets/images/**/*.@(jpg|png|gif|svg)", { base: 'src' })
.pipe(imagemin.default())
.pipe(dest('dist'))
}
const static = async () => {
return src("static/**", { base: 'static' })
.pipe(dest('dist'))
}
+const clean = () => {
+ return src("dist/**", { read: false })
+ .pipe(gulpClean())
+}
const compile = parallel(styles, scripts, html);
+const build = series(clean, parallel(compile, static));
exports.styles = styles;
exports.scripts = scripts;
exports.html = html;
exports.compile = compile;
exports.images = images;
exports.static = static;
exports.build = build;
+exports.clean = clean;
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
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
# 6.9 自动加载插件
const { src, dest, parallel, series } = require('gulp');
-const less = require('gulp-less');
-const babel = require('gulp-babel');
-const ejs = require('gulp-ejs');
-const gulpClean = require('gulp-clean');
+const plugins = require('gulp-load-plugins')();
const styles = () => {
return src("src/styles/*.less", { base: 'src' })
+ .pipe(plugins.less())
.pipe(dest('dist'))
}
const scripts = () => {
return src("src/scripts/*.js", { base: 'src' })
+ .pipe(plugins.babel({
presets: ["@babel/preset-env"]
}))
.pipe(dest('dist'))
}
const html = () => {
return src("src/*.html", { base: 'src' })
+ .pipe(plugins.ejs({ title: 'gulp' }))
.pipe(dest('dist'))
}
const images = async () => {
let imagemin = await import('gulp-imagemin');
return src("src/assets/images/**/*.@(jpg|png|gif|svg)", { base: 'src' })
.pipe(imagemin.default())
.pipe(dest('dist'))
}
const static = async () => {
return src("static/**", { base: 'static' })
.pipe(dest('dist'))
}
const clean = () => {
return src("dist/**", { read: false })
+ .pipe(plugins.clean())
}
const compile = parallel(styles, scripts, html);
const build = series(clean, parallel(compile, static));
exports.styles = styles;
exports.scripts = scripts;
exports.html = html;
exports.compile = compile;
exports.images = images;
exports.static = static;
exports.build = build;
exports.clean = clean;
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
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
# 6.10 开发服务器
# 6.10.1 gulpfile.js
const { src, dest, parallel, series } = require('gulp');
const plugins = require('gulp-load-plugins')();
+const browserSync = require('browser-sync');
+const path = require('path');
const styles = () => {
return src("src/styles/*.less", { base: 'src' })
.pipe(plugins.less())
.pipe(dest('dist'))
}
const scripts = () => {
return src("src/scripts/*.js", { base: 'src' })
.pipe(plugins.babel({
presets: ["@babel/preset-env"]
}))
.pipe(dest('dist'))
}
const html = () => {
return src("src/*.html", { base: 'src' })
.pipe(plugins.ejs({ title: 'gulp' }))
.pipe(dest('dist'))
}
const images = async () => {
let imagemin = await import('gulp-imagemin');
return src("src/assets/images/**/*.@(jpg|png|gif|svg)", { base: 'src' })
.pipe(imagemin.default())
.pipe(dest('dist'))
}
const static = async () => {
return src("static/**", { base: 'static' })
.pipe(dest('dist'))
}
const clean = () => {
return src("dist/**", { read: false })
.pipe(plugins.clean())
}
+const serve = () => {
+ return browserSync.create().init({
+ notify: false,
+ server: {
+ baseDir: 'dist',
+ routes: {
+ '/node_modules': path.resolve('node_modules')
+ }
+ }
+ });
+}
const compile = parallel(styles, scripts, html);
const build = series(clean, parallel(compile, static));
exports.styles = styles;
exports.scripts = scripts;
exports.html = html;
exports.compile = compile;
exports.images = images;
exports.static = static;
exports.build = build;
exports.clean = clean;
+exports.serve = serve;
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
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
# 6.10.2 main.js
src\scripts\main.js
let sum = (a, b) => a + b;
sum(1, 3)
+$(() => {
+ console.log('jquery');
+});
1
2
3
4
5
2
3
4
5
# 6.11 监听文件变化
# 6.11.1 gulpfile.js
const { src, dest, parallel, series, watch } = require('gulp');
const plugins = require('gulp-load-plugins')();
const browserSync = require('browser-sync');
const path = require('path');
+const browserServer = browserSync.create();
const styles = () => {
return src("src/styles/*.less", { base: 'src' })
.pipe(plugins.less())
.pipe(dest('dist'))
}
const scripts = () => {
return src("src/scripts/*.js", { base: 'src' })
.pipe(plugins.babel({
presets: ["@babel/preset-env"]
}))
.pipe(dest('dist'))
}
const html = () => {
return src("src/*.html", { base: 'src' })
+ .pipe(plugins.ejs({ title: 'gulp' }, { cache: false }))
.pipe(dest('dist'))
}
const images = async () => {
let imagemin = await import('gulp-imagemin');
return src("src/assets/images/**/*.@(jpg|png|gif|svg)", { base: 'src' })
.pipe(imagemin.default())
.pipe(dest('dist'))
}
const static = async () => {
return src("static/**", { base: 'static' })
.pipe(dest('dist'))
}
const clean = () => {
return src("dist/**", { read: false })
.pipe(plugins.clean())
}
const serve = () => {
+ watch("src/styles/*.less", styles);
+ watch("src/scripts/*.js", scripts);
+ watch("src/*.html", html);
+ watch([
+ "src/assets/images/**/*.@(jpg|png|gif|svg)",
+ "static/**"
+ ], browserServer.reload);
return browserServer.init({
notify: false,
+ files: ['dist/**'],
server: {
+ baseDir: ['dist', 'src', 'static'],
routes: {
'/node_modules': path.resolve('node_modules')
}
}
});
}
const compile = parallel(styles, scripts, html);
+const build = series(clean, parallel(compile, images, static));
+const dev = series(clean, compile, serve);
exports.styles = styles;
exports.scripts = scripts;
exports.html = html;
exports.compile = compile;
exports.images = images;
exports.static = static;
exports.clean = clean;
exports.serve = serve;
+exports.build = build;
+exports.dev = dev;
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
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
# 6.12. 合并和压缩
# 6.12.1 src\index.html
src\index.html
<!DOCTYPE html># 6.12.2 gulpfile.js
const { src, dest, parallel, series, watch } = require('gulp');
const plugins = require('gulp-load-plugins')();
const browserSync = require('browser-sync');
const path = require('path');
const browserServer = browserSync.create();
const styles = () => {
return src("src/styles/*.less", { base: 'src' })
.pipe(plugins.less())
+ .pipe(dest('temp'))
}
const scripts = () => {
return src("src/scripts/*.js", { base: 'src' })
.pipe(plugins.babel({
presets: ["@babel/preset-env"]
}))
+ .pipe(dest('temp'))
}
const html = () => {
return src("src/*.html", { base: 'src' })
.pipe(plugins.ejs({ title: 'gulp' }, { cache: false }))
+ .pipe(dest('temp'))
}
const images = async () => {
let imagemin = await import('gulp-imagemin');
return src("src/assets/images/**/*.@(jpg|png|gif|svg)", { base: 'src' })
.pipe(imagemin.default())
.pipe(dest('dist'))
}
const static = async () => {
return src("static/**", { base: 'static' })
.pipe(dest('dist'))
}
const clean = () => {
+ return src(["dist/**", "temp/**"], { read: false })
+ .pipe(plugins.clean({ allowEmpty: true }));
}
const serve = () => {
watch("src/styles/*.less", styles);
watch("src/scripts/*.js", scripts);
watch("src/*.html", html);
watch([
"src/assets/images/**/*.@(jpg|png|gif|svg)",
"static/**"
], browserServer.reload);
return browserServer.init({
notify: false,
files: ['dist/**'],
server: {
+ baseDir: ['temp', 'src', 'static'],
routes: {
'/node_modules': path.resolve('node_modules')
}
}
});
}
+const concat = () => {
+ return src('temp/*.html', { base: 'temp' })
+ .pipe(plugins.useref({
+ searchPath: ['temp', '.']
+ }))
+ .pipe(plugins.if('*.html', plugins.htmlmin({
+ collapseWhitespace: true,
+ minifyCSS: true,
+ minifyJS: true
+ })))
+ .pipe(plugins.if('*.js', plugins.uglify()))
+ .pipe(plugins.if('*.css', plugins.cleanCss()))
+ .pipe(dest('dist'));
+}
const compile = parallel(styles, scripts, html);
+const build = series(clean, parallel(series(compile, concat), images, static));
const dev = series(clean, compile, serve);
-exports.styles = styles;
-exports.scripts = scripts;
-exports.html = html;
-exports.compile = compile;
-exports.images = images;
-exports.static = static;
-exports.serve = serve;
-exports.concat = concat;
-exports.clean = clean;
-exports.build = build;
-exports.dev = dev;
+module.exports = {
+ clean,
+ build,
+ dev
+}
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
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
# 7. 参考知识
# 7.1 glob
gulp 内部使用了 node-glob 模块来实现其文件匹配功能
# 7.1.1 glob 规则
匹配符 | 说明 |
---|---|
* | 匹配文件路径中的 0 个或多个字符,但不会匹配路径分隔符 |
** | 匹配路径中的 0 个或多个目录及其子目录 |
? | 匹配文件路径中的一个字符(不会匹配路径分隔符) |
[...] | 匹配方括号中出现的字符中的任意一个,当方括号中第一个字符为^或!时,则表示不匹配方括号中出现的其他字符中的任意一个 |
!(pattern1 pattern2 pattern3) | 匹配任何与括号中给定的任一模式都不匹配的 |
?(pattern1 pattern2 pattern3) | 匹配括号中给定的任一模式 0 次或 1 次,类似于 js 正则中的(pattern1 pattern2 pattern3)? |
+(pattern1 patter2n pattern3) | 匹配括号中给定的任一模式至少 1 次,类似于 js 正则中的(pattern1 pattern2 pattern3)+ |
(pattern1 pattern2 pattern3) | 匹配括号中给定的任一模式 0 次或多次,类似于 js 正则中的(pattern1 pattern2 pattern3)* |
@(pattern1 pattern2 pattern3) | 匹配括号中给定的任一模式 1 次,类似于 js 正则中的(pattern1 pattern2 pattern3) |
# 7.1.2 glob 示例
glob | 匹配 |
---|---|
* | 能匹配 a.js,x.y,abc,abc/,但不能匹配 a/b.js . a.js,style.css,a.b,x.y |
//*.js | 能匹配 a/b/c.js,x/y/z.js,不能匹配 a/b.js,a/b/c/d.js |
** | 能匹配 abc,a/b.js,a/b/c.js,x/y/z,x/y/z/a.b,能用来匹配所有的目录和文件 |
a/**/z | 能匹配 a/z,a/b/z,a/b/c/z,a/d/g/h/j/k/z |
a/**b/z | 能匹配 a/b/z,a/sb/z,但不能匹配 a/x/sb/z,因为只有单**单独出现才能匹配多级目录 |
?.js | 能匹配 a.js,b.js,c.js |
a?? | 能匹配 a.b,abc,但不能匹配 ab/,因为它不会匹配路径分隔符 |
[xyz].js | 只能匹配 x.js,y.js,z.js,不会匹配 xy.js,xyz.js 等,整个中括号只代表一个字符 |
[^xyz].js | 能匹配 a.js,b.js,c.js 等,不能匹配 x.js,y.js,z.js |
2.基础概念 →