利用gulp实现前端代码的合并压缩

把之前一篇15年的文章移动过来~

gulp是什么?

看它的图标就是一杯可乐啊!

基于任务(流式)的自动化构建工具, 它能够自动完成js/css/sass/less等文件的测试, 检查, 压缩, 合并等工作. 众所周知, 前端的静态文件, 在上线前合并压缩是必不可少的. 给文件加上”版本号”, 防止浏览器缓存也是需要的, 不然修改了代码, 还需要用户不断的F5才能更新代码, 估计这个项目也就game over了.

工欲善其事,必先利其器; 这句话对于研发来说,真的是再合适不过. 而gulp就是这样的利器.

那如何来安装使用gulp呢?

  • 安装node环境 地址

  • 安装 gulp $ npm install -g gulp

  • 在项目 根目录下,新建文件 gulpfile.js

    1
    2
    3
    4
    var gulp = require('gulp');
    gulp.task('default',function(){
    //写两句代码看看,比如console.log("hello world");
    });
  • 运行 $ gulp

如何做合并压缩?

gulp运行起来了,我们真正的目的是要做合并压缩,如何来做?gulp为我们提供了很多的插件,它还有严格的插件机制保证插件为我们所用,gulp的API也是足够简单,4个API可以搞定绝大多数。

gulp的插件可以从这里寻找http://gulpjs.com/plugins/

  1. 压缩CSS:gulp-minify-css
  2. 压缩js : gulp-uglify
  3. 合并js: gulp-concat
  4. 压缩图片:gulp-imagemin
  5. 替换html中相应的文件块:gulp-useref
  6. 文件名加MD5后缀:gulp-rev
  7. 利用gulp-rev生成的manifest.json表替换html中的css和js引用:gulp-rev-replace

注:gulp-useref ,gulp-rev, gulp-rev-replace一般都是连用,他们三个的功能就是,把html文件中加了特定注释的文件区块进行合并,然后gulp-rev对文件加上md5,生存manifest.json,gulp-rev-replace再根据manifest.json文件替换html中对应的路径

gulp有很多插件,选择适合自己项目的,安装到项目中,在gulpfile.js中使用它们

1
$ npm install --save-dev gulp-minify-css gulp-uglify gulp-concat gulp-rev gulp-rev-replace gulp-useref
举个例子:合并压缩test.html文件中js文件并进行文件替换

test.html文件如下:

1
2
3
4
5
6
7
8
9
10
11
<!DOCTYPE html>
<html>
<head><title>test</title></head>
<body>
<div>hello world</div>
<!-- build:js({.tmp,src}) dist_test/js/main-combo.js -->
<script src="a.js"></script>
<script src="b.js"></script>
<!-- endbuild -->
</body>
</html>

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
var gulp = require('gulp'),
minifycss = require('gulp-minify-css'),
uglify = require('gulp-uglify'),
rev = require('gulp-rev'),
revReplace = require('gulp-rev-replace'),
useref = require('gulp-useref'),
concat = require('gulp-concat');
gulp.task('test-js',function(){
return gulp.src(["a.js","b.js"])
.pipe(uglify())
.pipe(concat('main-combo.js'))
.pipe(rev())
.pipe(gulp.dest("dist_test/js"))
.pipe(rev.manifest())
.pipe(gulp.dest("dist_test"));
});
gulp.task('test', ["test-js"],function() {
var manifest = gulp.src("dist_test/rev-manifest.json");
return gulp.src('test.html')
.pipe(useref())
.pipe(revReplace({manifest: manifest}))
.pipe(gulp.dest("dist_test"));
});

生成的项目目录如下

1
2
3
4
5
6
7
8
dist_test
js
main-combo-519cd1e2de.js
rev-manifest.json
test.html
test.html
a.js
b.js

dist_test下的test.html的文件内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
<!DOCTYPE html>
<html>
<head>
<title>test</title>
</head>
<body>
<div>hello world</div>

<script src="dist_test/js/main-combo-519cd1e2de.js"></script>

</body>
</html>

好了,dist_test就是我们需要上线的文件了~

PS:关于gulp-rev-replace的应用官方的例子我死活没有跑通,不知道什么原因,useref.assets()报错,console.log了下useref,居然没看到assets,所以用了上面提到的方法~

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
var gulp = require('gulp');
var rev = require('gulp-rev');
var revReplace = require('gulp-rev-replace');
var useref = require('gulp-useref');
var filter = require('gulp-filter');
var uglify = require('gulp-uglify');
var csso = require('gulp-csso');

gulp.task("index", function() {
var jsFilter = filter("**/*.js");
var cssFilter = filter("**/*.css");

var userefAssets = useref.assets();

return gulp.src("src/index.html")
.pipe(userefAssets) // Concatenate with gulp-useref
.pipe(jsFilter)
.pipe(uglify()) // Minify any javascript sources
.pipe(jsFilter.restore())
.pipe(cssFilter)
.pipe(csso()) // Minify any CSS sources
.pipe(cssFilter.restore())
.pipe(rev()) // Rename the concatenated files
.pipe(userefAssets.restore())
.pipe(useref())
.pipe(revReplace()) // Substitute in new filenames
.pipe(gulp.dest('public'));
});