本次打包大体过程是checkout出想要打包的git版本(能够是tag,也能够是branchName),而后依次读取项目中的html、less、js进行压缩合并等操做,复制项目中所用到的第三方库到输出目录(即plugins中的插件,好比lodash、echarts等,前边压缩合并的js是本身写的js),而后打zip包,发送至目的地。css
在gulp脚本中声明下载的gulp插件,即:html
var gulp = require('gulp'), concat = require('gulp-concat'), less = require('gulp-less'), minifyCss = require('gulp-minify-css'), minify = require('gulp-minify'), zip = require('gulp-zip'), moment = require("moment"), ftp = require('gulp-ftp'), git = require('gulp-git'), runSequence = require('run-sequence'), argv = require('minimist')(process.argv.slice(2)), del = require('del'), uglify = require('gulp-uglify'), htmlmin = require('gulp-htmlmin'), ngAnnotate = require('gulp-ng-annotate');
好比项目结构图以下:
那么这里配置的输入输出路径即为:
路径以gulpfile.js为参考位置。git
var path={ input:{ html:['src/app/*.html'], js:['src/app/js/*.js'], less:['src/app/less/*.less'], image:['src/app/image/*'], fonts:['src/app/fonts/*'], plugins:['src/plugins/**/*'] } output:{ dist:'dist', plugins:'dist/plugins' } }
若是不想要某文件,好比不想去压缩html1.htmlgulp
var path={ input:{ html:['src/app/*.html','!src/app/html1.html'], } }
'!'后面也能够跟某一类型文件,或者直接指定某文件夹。segmentfault
若是想打包git版本库中的某一个版本,或者某一个分支,就须要用到git.checkout,可是在checkout以前,须要首先提交git版本,若是在git-bash下,会进行以下操做。bash
git add . git commit -m “there are some comments”
在gulp中也同样,咱们须要编写以下代码服务器
gulp.task('commit', function(){ return gulp.src('./demo/**/*') .pipe(git.add()) .pipe(git.commit()); });
commit的必要性是若是在本地工做空间修改,而没有提交到本地仓库的话,代码有可能会丢。
上面这段代码也能够不写,不写的话,就须要每次执行gulp脚本以前,手动commit一下,总之,commit很重要。。。app
接下来,就要checkout出相关版本了,由于不能肯定打那个一版本的包,全部这里可能须要用命令行手动去指定一个版本,这里就用到了上篇提到的一个插件,minimist,插件具体就不在介绍了,这里直接上checkout的代码。echarts
gulp.task('checkout',[commit], function () { gitTag = argv.tag; git.checkout(gitTag, function (err) { if (err) throw err; }); })
其中argv.tag就是用了minimist获取的,命令行我会这样输入。less
gulp publish --tag v1.0.0
这种是指定tag的方式,还能够给gitTag 变量加一个默认值,即
gitTag = argv.tag||defaultValue;
这个defaultValue能够写死一个版本,也能够在每次commit的时候生成一个tag,gulp-git也有creat-tag的功能,这个方案我是没有去尝试的,理论上应该没啥问题,没有去用的主要缘由是,感受这样打的tag有点多了,因此仍是手动去给一个tag。
到这里,已经能够取出咱们要打包的项目代码了,下面开始进行具体打包工做。
压缩合并,简单来讲,就是指定须要处理的资源,而后调用相关函数,输出到某目录,等待下一步处理。
这里难度不大,直接上代码:
压缩html
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(config.input.html) .pipe(htmlmin(options)) .pipe(gulp.dest(config.output.dist))//gulp dest是输出 });
压缩合并JS
gulp.task('js', function (done) { return gulp.src(config.input.js) .pipe(ngAnnotate({single_quotes: true})) .pipe(uglify()) .pipe(concat('index.min.js')) .pipe(gulp.dest(config.output.dist)) });
编译压缩合并less
gulp.task('less', function () { return gulp.src(config.input.less) .pipe(less()) .pipe(minifyCss()) .pipe(concat('index.min.css')) .pipe(gulp.dest(config.output.dist)); });
复制第三方插件
gulp.task('copy', function (done) { return gulp.src(config.input.plugins) .pipe(gulp.dest(config.dist.plugins); });
正常状况进行过上面4步操做最后,会获得这样的结果:
通过合并压缩等操做以后,项目会自动生成dist目录,dist目录下即为打包生成的各类文件,接下来的目标是将dist目录下的全部文件打成一个zip包,代码以下:
gulp.task('zip_new', function () { var timeStamp = moment().format("YYYY-MM-D_HH-mm-ss_"); return gulp.src(config.input.zip) .pipe(zip("dist_" + timeStamp + ".zip")) .pipe(gulp.dest(config.output.dist)); });
moment是一个获取时间的插件,能够给打的包一个时间来标记,这个加不加都无所谓,zip方法里面就是zip包的名称,随意命名。
将zip包打好以后即可以发送zip包到某服务器了,代码以下:
gulp.task('ftp', function () { gulp.src("dist_zip/*") .pipe(ftp({ host: 'someHost', port: 21, //user: 'anonymous', //pass:null, remotePath: "somePath/" })); });
至这里,打包就所有完成了,下面要作的就是把他们连起来,这里用到上篇提到的插件,run-sequence,插件用法以下:
gulp.task('publish', function (callback) { runSequence(['html', 'js','less', 'copy'],'zip_new',ftp,callback); });
这里有两点须要注意:
1.run-sequence里面的任务,按顺序执行(方括号里面4个任务,算做一个任务),并且前一个跑完才会跑后一个,方括号里的是异步的,即不必定哪一个先完成。
2.要想达到第一点里面的同步执行(一个任务完成才开始下一个),必定要保证前面的全部任务,即除了ftp任务,其他的方法必定要是return出来的,即:
<font color=#20B2AA size=4>正确写法:</font>
gulp.task('js', function (done) { return gulp.src(config.input.js) .pipe(ngAnnotate({single_quotes: true})) .pipe(uglify()) .pipe(concat('index.min.js')) .pipe(gulp.dest(config.output.dist)) });
<font color=#DC143C size=4>错误写法:</font>
gulp.task('js', function (done) { gulp.src(config.input.js) .pipe(ngAnnotate({single_quotes: true})) .pipe(uglify()) .pipe(concat('index.min.js')) .pipe(gulp.dest(config.output.dist)) });
前边都要这样写,最后一项不加return,在本例中,即ftp的方法不用返回。
写到这里,还有一个问题,就是没有对文件夹进行清理,这也是比较重要的,在每一次开始打包工做以前,咱们须要清理dist目录,以保证下一次打包不会被上一次打包的文件“污染”。这里用到gulp-del的插件,代码以下:
gulp.task('clean',function(){ return del(config.output.dist); })
通过以上,一个完整的run-sequence以下:
gulp.task('publish', function (callback) { runSequence('clean','checkout',['html', 'js','less', 'copy'],'zip_new','ftp',callback); });
流程图: