使用gulp构建打包工具

由于工作的需要,最近都在研究gulp打包,昨天终于完成最终版本,今天上传了分支。
总结记录一些笔记。有需要的同学可以拿去用用哟!

需求

js&css压缩{输出}

--> js&css计算MD5并修改文件名

--> 图片压缩{输出}

--> 替换HTML里的js&css文件名

--> 压缩HTML代码{输出}

--> 将打包后输出的js&css文件上传至cdn

如何开始

1 首先你得已经安装了nodejs环境,然后依次按照下面的命令进行

1
2
3
4
5
6
7
$ npm install -g gulp               # 全局安装gulp

$ npm init # 初始化一些信息,项目名、作者等等,可以先随便填

$ npm install --save-dev gulp # 本地安装gulp,参数--save-dev会在package写入依赖

$ npm install --save-dev gulp-csso del gulp-rev # 根据gulpfile.js安装要用到的插件

2 项目目录结构

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
目录结构
.
├── app
│   ├── css // css下可以放外部导入css库,dist下可放页面样式
│   │   ├── a.css
│   │   ├── b.css
│   │   └── dist
│   │   └── c.css
│   ├── img
│   │   └── tg.png
│   └── js // js下放jq之类的外部库,pages下放页面js
│   ├── a.js
│   ├── main.js
│   └── pages
│   └── aa.js
├── config // 插件需要的配置文件,json里设置upyun信息
│   └── default.json
├── dist // 自动生成的输出目录
├── gulpfile.js
├── index.html
├── node_modules
├── package.json
└── rev // rev插件生成的文件,记录带了md5信息的文件
├── css
│   └── rev-manifest.json
└── js
└── rev-manifest.json

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
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
var gulp = require('gulp'),
del = require('del'), // 删除插件
rev = require('gulp-rev'), // 给文件增加md5后缀
revCollector = require('gulp-rev-collector'),// 根据rev替换文件名
htmlmin = require('gulp-htmlmin'), // html压缩
uglify = require('gulp-uglify'), // js混淆压缩
csso = require('gulp-csso'), // 压缩Css
cache = require('gulp-cache'), // 缓存插件,使图片仅更新缓存中不一样的图片
imagemin = require('gulp-imagemin'), // 压缩图片
runSequence = require('run-sequence'); // 改变任务优先级

// js压缩,替换为md5文件名
gulp.task('jsmin', function() {
return gulp.src('app/**/*.js')
.pipe(uglify())
.pipe(rev())
.pipe(gulp.dest('dist/app'))
.pipe(rev.manifest())
.pipe(gulp.dest('rev/js'));
});

// css压缩,替换为md5文件名 
gulp.task('cssmin', function() {
return gulp.src('app/**/*.css')
.pipe(csso())
.pipe(rev())
.pipe(gulp.dest('dist/app'))
.pipe(rev.manifest())
.pipe(gulp.dest('rev/css'));
});

// 替换html里的js和css链接,压缩html
gulp.task('rev',function(){
return gulp.src(['rev/**/*.json','*.html'])
.pipe(revCollector())
.pipe(htmlmin({
removeComments: true, // 去除注释
collapseWhitespace: true, // 去除空格
minifyJS: true, // 优化行内JS
minifyCSS: true // 优化行内样式
}))
.pipe(gulp.dest('dist'));
});


// 图片压缩优化
gulp.task('imagemin', function() {
return gulp.src('app/img/**/*.{png,jpg,gif,ico,svg}')
.pipe(cache(imagemin({
optimizationLevel: 5, //类型:Number 默认:3 取值范围:0-7(优化等级)
progressive: true, //类型:Boolean 默认:false 无损压缩jpg图片
interlaced: true, //类型:Boolean 默认:false 隔行扫描gif进行渲染
multipass: true //类型:Boolean 默认:false 多次优化svg直到完全优化
})))
.pipe(gulp.dest('dist/app/img'));
});

清理文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
* Clean
*/

// clean:bulid
// 删除dist里除了图片以外的资源
gulp.task('clean', function(callback) {
del(['dist/**/*', '!dist/app','!dist/app/img','!dist/app/img/**/*.{jpg,png,gif,ico,svg}'],callback);
});
// 清除dist所有资源
gulp.task('cleanAll', function(callback) {
del('dist')
return cache.clearAll(callback);
});

上传至又拍云

这里采用的是gulp-upyun插件,加上config,配置用户名密码。当然用户名和密码也可以直接写在gulpfile.js里。但是多少有点怪,所以我采取了使用config插件来配置,如果有什么更好的方式请务必要告诉我!:)真诚脸!

此外,一般来说我们管理cdn上的资源会采取ftp上管理,所以这里下载和删除可以省去,仅留下上传部分的代码既可。

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

/**
* UPYUN CDN
*/
var config = require('config');
var upyunSrc = require('gulp-upyun').upyunSrc; //获源
var upyunDest = require('gulp-upyun').upyunDest; //上传
var upyunRimraf = require('gulp-upyun').upyunRimraf; //删除

// 下载
gulp.task('upyundown',function(){
upyunSrc('gulpcs/dist/**/*',['!/gulpcs/dist/**/*.{png,jpg,gif,ico,svg}'],{
username: config.cdn.upyun.username,
password: config.cdn.upyun.password
})
.pipe(gulp.dest('out'));
})
// 上传
gulp.task('upyuncdn', function() {
return gulp.src('dist/**/*')
.pipe(upyunDest('gulpcs/' + config.cdn.upyun.folder, {
username: config.cdn.upyun.username,
password: config.cdn.upyun.password
}));
});
// 删除
gulp.task('upyundel',function(err){
upyunSrc('gulpcs/dist/**/*',{
username: config.cdn.upyun.username,
password: config.cdn.upyun.password
})
.pipe(upyunRimraf({
username: config.cdn.upyun.username,
password: config.cdn.upyun.password
}))
})

把任务组合到build、deploy中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
* Build
*/
// only modify file build test
gulp.task('build', function(callback) {
runSequence('clean',
['extendlib', 'jsmin', 'cssmin', 'mjsmin', 'mcssmin', 'imgmin'],
['htmlrev','mhtmlrev'],
callback)
});
// Build All
gulp.task('deploy', function(callback){
runSequence('build',
['upyuncdn'],
callback)
});

总结

这些都只是普通的简单应用,在简单的小型项目中使用也基本足够。我们还能使用gulp在开发过程中完成less或scss预处理,自动刷新等。具体过程可以查看参考链接。

gulp API docs

Gulp新手入门教程

前端构建工具gulpjs的使用介绍及技巧

gulp打造前端自动化工作流

用gulp做一个略完整的前端打包工作~

gulp简易入坑

坚持原创技术分享,您的支持将鼓励我继续创作!