前端一键打包发布

安装gulp

全局安装 gulp

1
2
$ npm install --global gulp

作为项目的开发依赖(devDependencies)安装

1
2
$ npm install --save-dev gulp

创建gulpfile.js文件

在项目根目录下创建一个名为 gulpfile.js 的文件:

1
2
3
4
gulp.task('default', function() {
// 将你的默认的任务代码放在这
});

运行 gulp

1
$ gulp default

编译Less

安装gulp-less

1
2
$ npm install gulp-less gulp-rename --save-dev
1
2
3
4
5
6
7
8
9
10
less = require('gulp-less'),//
rename = require('gulp-rename'), //文件重命名模块
//编译Less并且压缩改名*.min.css
gulp.task('Less', function () {
gulp.src('src/css', { base: '.' }) //该任务针对的文件
.pipe(rename({ suffix: '.min' }))
.pipe(less()) //该任务调用的模块
.pipe(gulp.dest('src/css'));
});

使用方法

1
2
$ gulp Less

编译Less&压缩改名

//编译Less并且压缩改名*.min.css

1
2
3
4
5
6
7
gulp.task('Less2', function () {
gulp.src('src/css', { base: '.' }) //该任务针对的文件
.pipe(rename({ suffix: '.min' }))
.pipe(less()) //该任务调用的模块
.pipe(cssmin()) //该任务调用的模块
.pipe(gulp.dest('src/css')); //将会在src/css下生成index.css
});

使用方法

1
2
$ gulp Less2

压缩&合并Css&改名

1
$ npm install cssmin concat --save-dev
1
2
3
cssmin = require('gulp-minify-css'), //压缩css
concat = require('gulp-concat'), //文件合并
1
2
3
4
5
6
7
8
//压缩合并Css改名*.min.css
gulp.task('CssConcat', function () {
gulp.src('src/css', { base: '.' })
.pipe(rename({ suffix: '.min' }))
.pipe(cssmin())
.pipe(concat('newname'))
.pipe(gulp.dest('src/css'))
});

使用方法

1
2
$ gulp CssConcat

压缩html

安装gulp-htmlmin

1
$ npm install gulp-htmlmin --save-dev
1
htmlmin = require('gulp-htmlmin'),
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
gulp.task('Html', function () {
var options = {
removeComments: true,
collapseWhitespace: true,
collapseBooleanAttributes: true,
removeEmptyAttributes: true,
removeScriptTypeAttributes: true,
removeStyleLinkTypeAttributes: true,
minifyJS: true,
minifyCSS: true
};
return gulp.src('src/html', { base: '.' })
.pipe(htmlmin(options))
.pipe(gulp.dest('src/html'))
});

使用

1
$ gulp Html

压缩jpg、png图片

安装gulp-imagemin

1
2
$ npm install gulp-imagemin gulpif --save-dev
1
2
imagemin = require('gulp-imagemin'), //图片压缩
gulpif = require('gulp-if'),
1
2
3
4
5
gulp.task('Image', function () {
return gulp.src('src/images', { base: '.' })
.pipe(gulpif([true,false], imagemin()))
.pipe(gulp.dest('src/images'));
});

使用

1
$ gulp Image

压缩JS

安装gulp-uglify

1
$ npm install gulp-uglify --save-dev
1
uglify = require('gulp-uglify'), //混淆js
1
2
3
4
5
gulp.task('JS', function () {
return gulp.src('src/js', { base: '.' })
.pipe(uglify())
.pipe(gulp.dest('src/js'));
});

使用方法

1
$ gulp JS

到目前为止,已经基本实现gulp打包压缩前端代码的核心功能,但是这远远还不够。因为在日常开发过程中我们会面临各种前端优化问题,比如缓存、发布、打包所带来的一系列问题。

一般情况下,我们前端开发就会想了解大公司是如何打包的?,在文章中,@张云龙有详细的介绍各种前端工程化,我就不做赘述了。如果你已经看完大公司是如何打包的?那么,你又没有想自己来试一试的想法呢。OK,我们来了解一下吧~~

既然如此,我们来看一下如何解决以下问题:

  1. 先发布应用(html)还是先发布资源(css、js、png、jpg等)?
  2. 如何实现资源精确缓存?
  3. 如何让浏览器主动放弃已经弃用的缓存?
  4. 如何把资源放到CDN节点上?

我们先把问题放一边,接下来继续改造我们的gulpfile.js文件

添加hash后缀

1
2
$ npm install gulp-rev --save-dev
1
2
rev = require('gulp-rev'), //更改hash版本号
1
2
3
4
5
6
7
//Css添加版本号
gulp.task('RevCss', function () {
return gulp.src('src/css')
.pipe(rev())
.pipe(rev.manifest())
.pipe(gulp.dest('./build' + '/rev/css'));
});

使用

1
2
$ gulp RevCss

执行完成之后这次会有不一样的地方,会在rev/css目录下面会生成一个rev-manifest.json的文件,这个文件将作为替换原始原件的依据并且打包到当前自定义目录./build/rev下,当然这个hash就是当前文件内容的哈希值

1
2
3
4
5
6
{
"css/animate.css": "css/animate-7a37992a94.css",
"css/front.css": "css/front-26561396d8.css",
"css/index.css": "css/index-38b95d80bb.css",
"script/plugins/layer_mobile/need/layer.css": "script/plugins/layer_mobile/need/layer-f6c02b5edb.css"
}

依此类推同理可写出js/png/jpg的哈希任务,如果文件更改,发布的时候哈希值自然就会发生改变,发布到服务器之后,html页面则会自动放弃以前失效的缓存。

精确管理缓存

精确管理缓存,顾名思义就是在html页面或者css页面中引用的资源文件加上hash后缀,并且自动替换成当前指定的文件,那现在就要用到文章上面提到的rev-manifest.json文件。

1
2
$ npm install gulp-rev-collector --save-dev
1
2
revCollector = require('gulp-rev-collector'),
1
2
3
4
5
6
7
8
9
gulp.task('RevHtml', function () {
return gulp.src(['./build/rev/**/*.json', './build/app/**/*.html'])
.pipe(revCollector(
{
replaceReved: true
}
))
.pipe(gulp.dest('./build' + '/app'));
});

使用方法

1
2
$ gulp RevHtml

执行完成之后再回到./build/app/看当前html页面指向的css是否已经变为css/index-38b95d80bb.css,如果是则恭喜你成功了,如果没有,你还需要斟酌一下~~
至于其他的css中有的图片或者html页面中有的js/image则都是一个道理,可以葫芦画瓢写多个task执行即可

把资源放到CDN节点上

放到CDN节点上无非就是更改已经发布好的源文件的资源文件链接,这里使用替换即可,也可使用其他方式实现。

1
2
$ npm install gulp-replace --save-dev
1
2
replace = require('gulp-replace'),
1
2
3
4
5
6
7
gulp.task('CDN', function () {
return gulp.src('./build/app/**/*.html')
.pipe(replace('../../static/css', 'http://cdn.com/css'))
.pipe(replace('../../static/js', 'http://cdn.com/js'))
.pipe(replace('../../static/image', 'http://cdn.com/image')
.pipe(gulp.dest('./build' + '/app'));
});

使用方法

1
2
$ gulp CDN

同理,在css文件或者其他文件中有引用资源文件就再写几个对应的task即可。

清除发布目录

OK,在执行之前需要清理一下当前发布目录./build

1
$ npm install gulp-clean --save-dev
1
clean = require('gulp-clean'), //删除
1
2
3
4
5
//清空发布目录
gulp.task('clean', function () {
return gulp.src('./build' + '/*', { read: false })
.pipe(clean());
});

使用方法

1
2
$ gulp clean

执行队列

那么,问题来了。这么多的task难道要一个一个的手动执行么?当然可以一次性搞定撒,要不然怎么叫一键打包发布呢?

1
2
3
4
5
//默认执行
gulp.task('build', function (cb) {
runSequence('clean',task1', 'task2','……','zip', cb);
});

只需执行build即可

1
2
$ gulp build

打包发布

OK,既然是一键打包发布,那么如何打包发布呢?那就要使用zip ftp

1
2
$ npm install gulp-zip gulp-ftp --save-dev
1
2
zip = require('gulp-zip'),
ftp = require('gulp-ftp'),
1
2
3
4
5
6
//打包
gulp.task('zip', function () {
gulp.src(fileConfig.output.dist + '/**/**')
.pipe(zip('name-20171011.zip'))
.pipe(gulp.dest('./build/build_zip'));
});
1
2
3
4
5
6
7
8
9
10
11
12
//上传
gulp.task('ftp', function () {
console.log('努力上传中...');
gulp.src("./build/build_zip/**")
.pipe(ftp({
host: 'ip',
port: port,
user: 'name',
pass: 'pwd',
remotePath: "projectname/20170101/"
}));
});

结束语

书接上文,在文章的中段,我抛出了几个问题,通读全文你是否已经有了答案?前端优化已经不再是html css js image简单问题,而是一个工程化问题:

  1. 配置超长时间的本地缓存 —— 节省带宽,提高性能
  2. 采用内容摘要作为缓存更新依据 ——精确的缓存控制
  3. 静态资源CDN部署 ——优化网络请求
  4. 资源发布路径实现非覆盖式发布 —— 平滑升级

当然,这个只是使用gulp来自己编写,也可使用fis来进行系统操作。

中文API

http://www.gulpjs.com.cn/docs/

------ 本文结束 ------

  • 本文作者: Xu Layen
  • 版权声明: 本博客所有文章除特别声明外,转载请注明出处!