之前一篇博客已经讲了gulp的基本用法,这一篇就开始实战了,现将这三个工具的概念和使用,最后是实际操作的例子。
1 gulp-concat
这个插件用于将多个文件合并成一个大文件。
举例如下:
现lib目录下有3个js文件,可以使用gulp-concat将其按照指定顺序合并成为1个js文件。
gulpfile.js写一个task(scripts)的内容如下:
var gulp = require('gulp');
var concat = require('gulp-concat');
gulp.task('scripts', function() {
return gulp.src(['./lib/file3.js', './lib/file1.js', './lib/file2.js'])
.pipe(concat({ path: 'new.js', stat: { mode: 0666 }}))
.pipe(gulp.dest('./dist'));
});
出于简便考虑,3个js文件都只是简单的进行了赋值。
file1.js:
var aaa = 111;
file2.js:
var bbb = 222;
file3.js:
var ccc = 333;
在命令行中执行gulp scripts
命令,
可以看到在根目录下多了一个文件夹dist,其中的new.js包含了这三个js文件的内容:
并且顺序也是按照我们指定的file3->file1->file2。
合并的时候还可以与source maps搭配使用,sourcemaps可以防止代码压缩之后无法定位报错的位置,便于debug。
var gulp = require('gulp');
var concat = require('gulp-concat');
var sourcemaps = require('gulp-sourcemaps');
gulp.task('scripts', function() {
return gulp.src(['./lib/file3.js', './lib/file1.js', './lib/file2.js'])
.pipe(sourcemaps.init())
.pipe(concat({ path: 'new.js', stat: { mode: 0666 }}))
.pipe(sourcemaps.write())
.pipe(gulp.dest('./dist'));
});
其结果就是new.js里面多了一行注释:
2 gulp-uglify
这个插件的作用是将大文件压缩,例如去掉空格,改变变量名称,去掉注释等。
还是之前例子的new.js:
var ccc = 333;
var aaa = 111;
var bbb = 222;
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZpbGUzLmpzIiwiZmlsZTEuanMiLCJmaWxlMi5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBO0FDQUEiLCJmaWxlIjoibmV3LmpzIiwic291cmNlc0NvbnRlbnQiOlsidmFyIGNjYyA9IDMzMzsiLCJ2YXIgYWFhID0gMTExOyIsInZhciBiYmIgPSAyMjI7Il19
在gulpfile.js中再写一个task(compress):
var gulp = require('gulp');
var concat = require('gulp-concat');
var sourcemaps = require('gulp-sourcemaps');
var uglify = require('gulp-uglify');
var pump = require('pump');
gulp.task('scripts', function() {
return gulp.src(['./lib/file3.js', './lib/file1.js', './lib/file2.js'])
.pipe(sourcemaps.init())
.pipe(concat({ path: 'new.js', stat: { mode: 0666 }}))
.pipe(sourcemaps.write())
.pipe(gulp.dest('./dist'));
});
gulp.task('compress', function (cb) {
pump([
gulp.src('new.js'),
uglify(),
gulp.dest('dist')
],
cb
);
});
在命令行中执行gulp compress
命令
产生的结果文件如下:
可以看到变量定义都合并到了一起,注释也被删掉了。
3 gulp-cdnizer
这个插件的作用是把本地的框架和大型库的代码替换成cdn,以加快框架和库的加载速度,cdn的优势这里就不赘述了,前端的同学应该都明白。
举例如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Webapp</title>
<!--bower:css-->
<link rel="stylesheet" href="/bower_components/bootstrap/dist/css/bootstrap.css">
<link rel="stylesheet" href="/bower_components/font-awesome/css/font-awesome.css">
<link rel="stylesheet" href="/bower_components/bootstrap-datepicker/dist/css/bootstrap-datepicker3.css">
<link rel="stylesheet" href="/bower_components/ng-dialog/css/ngDialog.css">
<link rel="stylesheet" href="/bower_components/ng-dialog/css/ngDialog-theme-default.css">
<link rel="stylesheet" href="/bower_components/pickadate/lib/themes/default.css">
<link rel="stylesheet" href="/bower_components/pickadate/lib/themes/default.date.css">
<link rel="stylesheet" href="/bower_components/pickadate/lib/themes/default.time.css">
<link rel="stylesheet" href="/bower_components/bootstrap-treeview/dist/bootstrap-treeview.min.css">
<!--endinject-->
<!--bower:js-->
<script src="/bower_components/jquery/dist/jquery.js"></script>
<script src="/bower_components/angular/angular.js"></script>
<script src="/bower_components/angular-animate/angular-animate.js"></script>
<script src="/bower_components/lodash/lodash.js"></script>
<script src="/bower_components/ng-file-upload/ng-file-upload.js"></script>
<script src="/bower_components/angular-ui-router/release/angular-ui-router.js"></script>
<script src="/bower_components/angular-mocks/angular-mocks.js"></script>
<script src="/bower_components/mathjs/dist/math.min.js"></script>
<script src="/bower_components/bootstrap-datepicker/dist/js/bootstrap-datepicker.min.js"></script>
<script src="/bower_components/validate/validate.js"></script>
<script src="/bower_components/moment/moment.js"></script>
<script src="/bower_components/ng-dialog/js/ngDialog.js"></script>
<script src="/bower_components/angular-bootstrap/ui-bootstrap-tpls.js"></script>
<script src="/bower_components/ngstorage/ngStorage.js"></script>
<script src="/bower_components/angular-jwt/dist/angular-jwt.js"></script>
<script src="/bower_components/restangular/dist/restangular.js"></script>
<script src="/bower_components/spin.js/spin.js"></script>
<script src="/bower_components/raven-js/dist/raven.min.js"></script>
<script src="/bower_components/raven-js/dist/plugins/angular.min.js"></script>
<script src="/bower_components/pickadate/lib/picker.js"></script>
<script src="/bower_components/pickadate/lib/picker.date.js"></script>
<script src="/bower_components/pickadate/lib/picker.time.js"></script>
<script src="/bower_components/bluebird/js/browser/bluebird.js"></script>
<script src="/bower_components/bootstrap-treeview/dist/bootstrap-treeview.min.js"></script>
<script src="/bower_components/angular-spinner/angular-spinner.js"></script>
<script src="/bower_components/angular-loading-spinner/angular-loading-spinner.js"></script>
<!--endinject-->
</head>
<body ng-app="EDCAPP">
<div>
<ui-view></ui-view>
<span us-spinner></span>
</div>
</body>
</html>
有大量的通过bower下载的框架和库,如果不做优化,而让浏览器从服务器请求的话会非常的占用时间,直接后果就是首屏时间过长,破坏用户体验。
所以在gulpfile.js
里再写一个task(cdn):
var gulp = require('gulp');
var concat = require('gulp-concat');
var sourcemaps = require('gulp-sourcemaps');
var uglify = require('gulp-uglify');
var pump = require('pump');
var cdnizer = require("gulp-cdnizer");
//前面的部分省略了
gulp.task('cdn',function() {
gulp.src("index.html")
.pipe(cdnizer([
'cdnjs:bootstrap',
'cdnjs:font-awesome',
'cdnjs:bootstrap-datepicker',
'cdnjs:ng-dialog',
'cdnjs:pickadate.js@3.5.6',
'cdnjs:bootstrap-treeview@1.2.0',
'cdnjs:jquery',
'cdnjs:angular.js',
'cdnjs:angular.js:angular-animate.js',
'cdnjs:angular.js:angular-mocks.js',
'cdnjs:lodash.js@4.17.4',
'cdnjs:danialfarid-angular-file-upload',
'cdnjs:angular-ui-router.statehelper',
'cdnjs:mathjs',
'cdnjs:bootstrap-datepicker',
'cdnjs:validate.js@0.11.1',
'cdnjs:moment.js@2.10.0',
'cdnjs:ng-dialog',
'cdnjs:ngStorage@0.3.6',
'cdnjs:restangular',
'cdnjs:spin.js',
'cdnjs:raven.js@3.11.0',
'cdnjs:bluebird',
'cdnjs:bootstrap-treeview@1.2.0',
'cdnjs:angular-spinner@0.8.1'
]))
.pipe(gulp.dest("./dist"));
});
这样,当我们执行gulp cdn
的时候,就会把原index.html
的库都替换成cdn。
注意:实际使用中单一的cdn不一定可以满足所有的需求,所以要多收藏几个大型的cdn备用,如果都无法找到,则需要用fallback
的功能,从本地获取,fallback
默认都是开启的,这个不用操心了,具体的用法还是参考官网吧。
//节选了部分输出的结果
<!--bower:js-->
<!--有效--><script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script><script>if(!(window.jQuery)) cdnizerLoad("/bower_components/jquery/dist/jquery.js");</script>
<!--有效--><script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.11/angular.min.js"></script><script>if(!(window.angular)) cdnizerLoad("/bower_components/angular/angular.js");</script>
<!--有效--><script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.11/angular-animate.js"></script><script>if(!(window.angular)) cdnizerLoad("/bower_components/angular-animate/angular-animate.js");</script>
<!--有效--><script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
<!--没找到--><script src="/bower_components/ng-file-upload/ng-file-upload.js"></script>
<!--没找到--><script src="/bower_components/angular-ui-router/release/angular-ui-router.js"></script>
<!--有效--><script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.11/angular-mocks.js"></script><script>if(!(window.angular)) cdnizerLoad("/bower_components/angular-mocks/angular-mocks.js");</script>
<!--有效--><script src="//cdnjs.cloudflare.com/ajax/libs/mathjs/3.9.3/math.min.js"></script>
<!--有效--><script src="//cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.6.4/js/bootstrap-datepicker.min.js"></script>
<!--有效--><script src="//cdnjs.cloudflare.com/ajax/libs/validate.js/0.11.1/validate.min.js"></script>
<!--有效--><script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.0/moment.min.js"></script>
<!--有效--><script src="//cdnjs.cloudflare.com/ajax/libs/ng-dialog/0.6.6/js/ngDialog.min.js"></script>
<!--没找到--><script src="/bower_components/angular-bootstrap/ui-bootstrap-tpls.js"></script>
<!--有效--><script src="//cdnjs.cloudflare.com/ajax/libs/ngStorage/0.3.6/ngStorage.min.js"></script>
<!--无法访问--><script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.11/angular-jwt.js"></script><script>if(!(window.angular)) cdnizerLoad("/bower_components/angular-jwt/dist/angular-jwt.js");</script>
<!--有效--><script src="//cdnjs.cloudflare.com/ajax/libs/restangular/1.6.1/restangular.min.js"></script>
<!--有效--><script src="//cdnjs.cloudflare.com/ajax/libs/spin.js/2.0.1/spin.min.js"></script>
<!--有效--><script src="//cdnjs.cloudflare.com/ajax/libs/raven.js/3.11.0/raven.min.js"></script>
<!--有效--><script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.11/angular.min.js"></script><script>if(!(window.angular)) cdnizerLoad("/bower_components/raven-js/dist/plugins/angular.min.js");</script>
<!--有效--><script src="//cdnjs.cloudflare.com/ajax/libs/pickadate.js/3.5.6/picker.js"></script>
<!--没找到--><script src="/bower_components/pickadate/lib/picker.date.js"></script>
<!--没找到--><script src="/bower_components/pickadate/lib/picker.time.js"></script>
<!--有效--><script src="//cdnjs.cloudflare.com/ajax/libs/bluebird/3.4.7/bluebird.min.js"></script>
<!--替换失败--><script src="/bower_components/bootstrap-treeview/dist/bootstrap-treeview.min.js"></script>
<!--有效--><script src="//cdnjs.cloudflare.com/ajax/libs/angular-spinner/0.8.1/angular-spinner.min.js"></script>
<!--没找到--><script src="/bower_components/angular-loading-spinner/angular-loading-spinner.js"></script>