gulp自動化打包(下)

打包流程簡介

本次打包大體過程是checkout出想要打包的git版本(能夠是tag,也能夠是branchName),而後依次讀取項目中的html、less、js進行壓縮合並等操做,複製項目中所用到的第三方庫到輸出目錄(即plugins中的插件,好比lodash、echarts等,前邊壓縮合並的js是本身寫的js),而後打zip包,發送至目的地。
這裏寫圖片描述css

開始編寫gulp腳本

聲明gulp插件

在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

使用gulp-git

若是想打包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步操做最後,會獲得這樣的結果:
打包以後

打zip包

通過合併壓縮等操做以後,項目會自動生成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目錄

寫到這裏,還有一個問題,就是沒有對文件夾進行清理,這也是比較重要的,在每一次開始打包工做以前,咱們須要清理dist目錄,以保證下一次打包不會被上一次打包的文件「污染」。這裏用到gulp-del的插件,代碼以下:

gulp.task('clean',function(){
  return del(config.output.dist);
})

完整打包review

通過以上,一個完整的run-sequence以下:

gulp.task('publish', function (callback) {
  runSequence('clean','checkout',['html', 'js','less', 'copy'],'zip_new','ftp',callback);
});

流程圖:
打包流程圖

相關文章
相關標籤/搜索