概览

由于公司需求,需要使用 gulp 构建项目,总结一下自己使用 gulp 构建的项目

耗时

由于从来都没有接触过,所以耗时这块事件有点长,从开始搭建,到搭建完成用了 6 个小时左右。期间主要是查看官方文档和插件文档以及找插件。

难点

并没有多少难点,估计是我做的不是太深入,项目比较简单的原因。唯一比较难受的地方就是起本地服务以、代理、抽离组件的时候耗费了一点时间,绝大多数时间都是在看文档。

工具

gulp4.x

注意 3.x 和 4.x 的语法稍有区别

插件

前置环境

  • nodejs
  • npm
  • npx

学习 gulp

gulp 是什么、有什么用

  • gulp是一个基于流的自动化构建工具
  • gulp 将开发流程中让人痛苦或耗时的任务自动化,从而减少你所浪费的时间、创造更大价值

gulp API

gulp.task

  • 语法:gulp.task(任务名称,任务处理函数)
  • 作用:创建一个基于流的任务
  • eg:gulp.task(xxx,func(){})

gulp.src()

  • 语法:gulp.src(路径)
  • 作用:找到源文件
  • 书写方式:
    • gulp.src(‘./a/b.html’)
    • gulp.src(‘./*/.html’)
    • ……

gulp.dest()

  • 语法:gulp.dest(路径)
  • 作用:把得到的流输出到目标文件目录
  • eg:gulp.dest(‘./xxx’)

gulp.watch()

  • 语法:gulp.watch(路径,任务名称)
  • 作用:监控制定目录下的文件,一旦发生变化,从新执行后面的任务
  • eg:gulp.watch(‘./src/pages/* _ / _.html’,htmlHander)
    • 当 pages 文件下的任何.html 文件发生变化,就会执行 htmlHander 任务

gulp.series()

  • 语法:gulp.series(任务 1,任务 2,任务 3,。。。)
  • 作用:逐个执行多个任务,前一个任务结束,第二个任务开始

gulp.parallel()

  • 语法:gulp.parallel(任务 1,任务 2,任务 3,。。。)
  • 作用:并行执行多个任务,其中一个失败,不影响其他任务

pipe()

  • 语法:gulp.xxx().pipe(插件函数())
  • 作用:管道函数,所有的 gulp API 都是基于流的
  • 管道:接受当前流,进入下一个流的过程称为管道函数

环境搭建

API 了解完了,下面开始进行项目构建

约定

下面所有的案例都默认引入了

const gulp = require(“gulp”);

除非特别声明外,创建gulpfile.js文件并且所有的代码都写在 gulpfile.js文件内

同一类型文件操作叠加,例如,1-1 是压缩 css,1-2 清除 css 会包含压缩 css,但是不会在重新引入插件

插件的使用方法和官方地址上面已经列出,一面不做讲解

压缩 css

1
yarn add gulp-cssmin -S -D
1
2
3
4
5
6
7
8
9
const cssmin = require("gulp-cssmin");
const cssHandler = function () {
return gulp
.src("./src/pages/**/*.less")
.pipe(cssmin()) // css 代码压缩
.pipe(gulp.dest("./dist/pages/")); // 打包到的目录
};

module.exports.dev = cssHandler;

清除 css

1
yarn add gulp-clean-css -S -D
1
2
3
4
5
6
7
8
9
10
const cleanCSS = require("gulp-clean-css");
const cssHandler = function () {
return gulp
.src("./src/pages/**/*.less")
.pipe(cleanCSS())
.pipe(cssmin()) // css 代码压缩
.pipe(gulp.dest("./dist/pages/")); // 打包到的目录
};

module.exports.dev = cssHandler;

重命名

可用在任何文件中,所以下方需要的话,会直接使用上

1
yarn add gulp-rename -S -D
1
2
3
4
5
6
7
8
9
10
const rename = require("gulp-rename");

const cssHandler = function () {
return gulp
.src("./src/pages/**/*.less")
.pipe(cleanCSS())
.pipe(cssmin()) // css 代码压缩
.pipe(rename({ extname: ".min.css" }))
.pipe(gulp.dest("./dist/pages/")); // 打包到的目录
};

对 less 进行转换

sass 于此类似 插件为 gulp-sass

1
yarn add gulp-less -S -D
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const less = require("gulp-less");

const cssHandler = function () {
return gulp
.src("./src/pages/**/*.less")
.pipe(
less({
paths: [path.join(__dirname, "less", "includes")],
})
)
.pipe(cleanCSS())
.pipe(cssmin()) // css 代码压缩
.pipe(rename({ extname: ".min.css" }))
.pipe(gulp.dest("./dist/pages/")); // 打包到的目录
};

对 css 处理,添加浏览器前缀

1
yarn add less-plugin-autoprefix -S -D
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const LessAutoprefix = require("less-plugin-autoprefix");
const autoprefix = new LessAutoprefix({ browsers: ["last 2 versions"] });

const cssHandler = function () {
return gulp
.src("./src/pages/**/*.less")
.pipe(
less({
paths: [path.join(__dirname, "less", "includes")],
plugins: [autoprefix],
})
)
.pipe(cleanCSS())
.pipe(cssmin()) // css 代码压缩
.pipe(rename({ extname: ".min.css" }))
.pipe(gulp.dest("./dist/pages/")); // 打包到的目录
};

html 压缩

1
yarn add gulp-htmlmin -S -D
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const htmlmin = require("gulp-htmlmin");

const htmlHomeHandler = function () {
return gulp
.src("./src/*.html")
.pipe(
htmlmin({
collapseWhitespace: true, // 去重空格
removeEmptyAttributes: true,
minifyCSS: true, //压缩 html 的 style
minifyJS: true,
minifyURLs: true,
})
)
.pipe(rename({ extname: ".min.html" }))
.pipe(gulp.dest("./dist/"));
};

js 压缩

1
yarn add gulp-uglify -S -D
1
2
3
4
5
6
7
8
9
const uglify = require("gulp-uglify");

const jsHandler = function () {
return gulp
.src("./src/pages/**/*.js")
.pipe(uglify()) // js 代码压缩
.pipe(rename({ extname: ".min.js" }))
.pipe(gulp.dest("./dist/pages")); // 打包到的目录
};

压缩图片

1
yarn add gulp-imagemin -S -D
1
2
3
4
5
6
7
8
const imagemin = require("gulp-imagemin");

const imgHandler = function () {
return gulp
.src("./src/assets/img/*.*")
.pipe(imagemin())
.pipe(gulp.dest("./dist/assets/img"));
};

清除文件

1
yarn add gulp-clean -S -D
1
2
3
4
5
const clearDist = require("gulp-clean");

const clearDistFile = function () {
return gulp.src(["dist/*"]).pipe(clearDist());
};

开启本地服务

1
yarn add gulp-webserver -S -D
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const server = require("gulp-webserver");

const serverHandler = function () {
return gulp.src("./dist").pipe(
server({
host: "127.0.0.1",
prot: "8080",
livereload: true,
open: "./pages/index/index.min.html",
proxies: [
{
source: "/api/v1",
target: "http://192.168.101.13:8080/api/v1/", //目标服务器
},
],
})
);
};

监听文件变化

1
2
3
4
5
const watchFile = function () {
gulp.watch("src/**/*.less", cssHandler);
gulp.watch("src/**/*.js", jsHandler);
gulp.watch("src/**/*.html", htmlProductsHandler, htmlHomeHandler);
};

组件抽离

1
yarn add gulp-file-include -S -D
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
const fileinclude = require("gulp-file-include");

const htmlProductsHandler = function () {
return gulp
.src("./src/pages/**/*.html")
.pipe(
fileinclude({
prefix: "@@",
basepath: "@file",
})
)
.pipe(
htmlmin({
collapseWhitespace: true, // 去重空格
removeEmptyAttributes: true,
minifyCSS: true, //压缩 html 的 style
minifyJS: true,
minifyURLs: true,
})
)
.pipe(rename({ extname: ".min.html" }))
.pipe(gulp.dest("./dist/pages/"));
};

使用方式:

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
<!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>
<link rel="stylesheet" href="./index.min.css" />
<link rel="stylesheet" href="../../components/footer/index.min.css" />
</head>
<body>
@@include('../../components/header/index.html')
<div>
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Porro,
voluptate sequi? Corrupti quos nobis id culpa quibusdam similique qui
sunt! At quis quaerat ab. Reiciendis error natus debitis animi esse
aspernatur eveniet.
</div>
<div>Lorem, ipsum.</div>
<div>Eius, fugit.</div>
<div>Temporibus, autem.</div>
@@include('../../components/footer/index.html')
<script src="../../lib/jquery.min.js"></script>
<script src="./index.min.js"></script>
<script src="../../components/footer/index.min.js"></script>
</body>
</html>

所有详细使用请查看文档

组合任务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
module.exports.dev = gulp.series(
clearDistFile,
gulp.parallel(
cssHandler,
cssPubHandler,
otherHandler,
htmlHomeHandler,
jsHandler,
htmlProductsHandler,
jsCompontHandler,
cssCompontHandler,
imgHandler,
jQueryHandler
),
serverHandler,
watchFile
);

package.json 文件中配置启动

配置的是由 npx gulp 加上 gulpfile.js 导出的任务名称

1
2
3
"scripts": {
"start":"npx gulp dev"
},

启动方式

  • 方式一

yarn start | npm run start

  • 方式二

npx gulp dev | gulp 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
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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
Skip to content
Search or jump to…

Pull requests
Issues
Marketplace
Explore

@pythongyj
pythongyj
/
gulp-temp-demo
1
00
Code
Issues
Pull requests
Actions
Projects
Wiki
Security
Insights
Settings
gulp-temp-demo/gulpfile.js /
@pythongyj
pythongyj init
Latest commit 6926e3b 6 minutes ago
History
1 contributor
204 lines (187 sloc) 4.94 KB

const gulp = require("gulp");
// 压缩 css 函数工具
const cssmin = require("gulp-cssmin");
// 压缩 html 函数工具
const htmlmin = require("gulp-htmlmin");
// 压缩 js 函数工具
const uglify = require("gulp-uglify");
// 压缩图片函数工具
const imagemin = require("gulp-imagemin");
// 清除css
const cleanCSS = require("gulp-clean-css");

const less = require("gulp-less");

const LessAutoprefix = require("less-plugin-autoprefix");
const autoprefix = new LessAutoprefix({ browsers: ["last 2 versions"] });
const clearDist = require("gulp-clean");

const path = require("path");
const rename = require("gulp-rename");
const server = require("gulp-webserver");

const fileinclude = require("gulp-file-include");

// 转化less 添加前缀并压缩
const cssHandler = function () {
return gulp
.src("./src/pages/**/*.less")
.pipe(
less({
paths: [path.join(__dirname, "less", "includes")],
plugins: [autoprefix],
})
)
.pipe(cleanCSS())
.pipe(cssmin()) // css 代码压缩
.pipe(rename({ extname: ".min.css" }))
.pipe(gulp.dest("./dist/pages/")); // 打包到的目录
};

// 转化公有less 添加前缀并压缩
const cssPubHandler = function () {
return gulp
.src("./src/accets/*.less")
.pipe(
less({
paths: [path.join(__dirname, "less", "includes")],
plugins: [autoprefix],
})
)
.pipe(cleanCSS())
.pipe(cssmin()) // css 代码压缩
.pipe(rename({ extname: ".min.css" }))
.pipe(gulp.dest("./dist/accets/")); // 打包到的目录
};

// 压缩首页
const htmlHomeHandler = function (cb) {
cb();
return gulp
.src("./src/*.html")
.pipe(
fileinclude({
prefix: "@@",
})
)
.pipe(
htmlmin({
collapseWhitespace: true, // 去重空格
removeEmptyAttributes: true,
minifyCSS: true, //压缩 html 的 style
minifyJS: true,
minifyURLs: true,
})
)
.pipe(rename({ extname: ".min.html" }))
.pipe(gulp.dest("./dist/"));
};

// 压缩页面
const htmlProductsHandler = function () {
return gulp
.src("./src/pages/**/*.html")
.pipe(
fileinclude({
prefix: "@@",
basepath: "@file",
})
)
.pipe(
htmlmin({
collapseWhitespace: true, // 去重空格
removeEmptyAttributes: true,
minifyCSS: true, //压缩 html 的 style
minifyJS: true,
minifyURLs: true,
})
)
.pipe(rename({ extname: ".min.html" }))
.pipe(gulp.dest("./dist/pages/"));
};

// 打包页面压缩js文件
const jsHandler = function () {
return gulp
.src("./src/pages/**/*.js")
.pipe(uglify()) // js 代码压缩
.pipe(rename({ extname: ".min.js" }))
.pipe(gulp.dest("./dist/pages")); // 打包到的目录
};

// 打包组件压缩js文件
const jsCompontHandler = function () {
return gulp
.src("./src/components/**/*.js")
.pipe(uglify()) // js 代码压缩
.pipe(rename({ extname: ".min.js" }))
.pipe(gulp.dest("./dist/components")); // 打包到的目录
};

// 转化组件less 添加前缀并压缩
const cssCompontHandler = function () {
return gulp
.src("./src/components/**/*.less")
.pipe(
less({
paths: [path.join(__dirname, "less", "includes")],
plugins: [autoprefix],
})
)
.pipe(cleanCSS())
.pipe(cssmin()) // css 代码压缩
.pipe(rename({ extname: ".min.css" }))
.pipe(gulp.dest("./dist/components/")); // 打包到的目录
};

// 转移jq文件
const jQueryHandler = function () {
return gulp
.src("./node_modules/jquery/dist/jquery.min.js")
.pipe(gulp.dest("./dist/lib")); // 打包到的目录
};

// 转移第三方文件
const otherHandler = function () {
return gulp
.src("./src/lib/**")
.pipe(gulp.dest("./dist/lib")); // 打包到的目录
};

// 打包图片
const imgHandler = function () {
return gulp
.src("./src/assets/img/*.*")
.pipe(imagemin())
.pipe(gulp.dest("./dist/assets/img"));
};

// 清除dist文件夹下的所有文件
const clearDistFile = function () {
return gulp.src(["dist/*"]).pipe(clearDist());
};

// 监听文件变化
const watchFile = function () {
gulp.watch("src/**/*.less", cssHandler);
gulp.watch("src/**/*.js", jsHandler);
gulp.watch("src/**/*.html", htmlProductsHandler, htmlHomeHandler);
};

// 开启本地服务,代理接口
const serverHandler = function () {
return gulp.src("./dist").pipe(
server({
host: "127.0.0.1",
prot: "8080",
livereload: true,
open: "./pages/index/index.min.html",
proxies: [
{
source: "/api/v1",
target: "http://192.168.101.13:8080/api/v1/",
},
],
})
);
};
module.exports.dev = gulp.series(
clearDistFile,
gulp.parallel(
cssHandler,
cssPubHandler,
otherHandler,
htmlHomeHandler,
jsHandler,
htmlProductsHandler,
jsCompontHandler,
cssCompontHandler,
imgHandler,
jQueryHandler
),
serverHandler,
watchFile
);

好记性不如烂笔头,总结的有欠缺的地方如有人看到请帮忙指出,谢谢!