gulp自動化打包(上)
轉載自:http://blog.csdn.net/j_bleach/article/details/53047467
文章概述
本文分為上下兩篇,上篇主要介紹一些常用的gulp外掛(也是此次打包主要用的gulp外掛),而下篇主要以一個demo專案為例,從本地checkout出合適的Git版本,壓縮、合併、到最後打成zip包,傳送至指定目錄,做一個全面的演示。
流程預覽:
專案結構
首先,有一個類似於這樣的專案結構
圖中主要演示專案中大概會有的幾種檔案型別,fonts(ttf,svg),image(jpg,png),js,less(sass),實際專案會複雜得多,開始一個專案的時候,可以直接從git上拿一個angular-seed(webpack-seed)改。
開始使用gulp
下載gulp
開始玩gulp之前,要確定自己有nodejs的環境,沒有的話,先去弄個nodejs,這個比較簡單,直接在https://nodejs.org/en/,下載一個對應開發環境的nodejs,然後一路next,路徑預設就好,window下自定義了路徑後,就不是全域性的了,需要自己再配環境變數,圖省事的話,就一路next到finish。
ok,安裝好nodejs之後,在專案的src目錄下(與index.html的同級目錄)建立一個package.json檔案與gulpfile.js(這個名字要對,不然命令列識別不了,專案中有時建立兩個gulp的js檔案,如果兩個都含有同一任務,不特殊說明的話,命令列只執行檔名為gulpfile.js的任務),在命令列輸入 npm install gulp --save-dev
npm
install gulp -g --save-dev
)指令, “–save-dev”表示在安裝gulp之後,將安裝的資訊儲存在package.json檔案,以便之後利用package.json檔案去install相關外掛(多人開發尤其要注意儲存安裝資訊),建立gulp成功後,目錄結構變為
之後所有的gulp外掛都以此方式安裝,即
npm install xx --save-dev
gulp外掛詳細介紹
按照實際的打包順序, 我依次會介紹gulp-git、gulp-htmlmin、gulp-uglify、gulp-concat、gulp-ng-annotate
gulp-less、gulp-minify-css、minimist、del、gulp-zip、gulp-ftp、run-sequence
gulp-git
gulp-git主要的作用是通過gulp指令碼,來執行一些git的操作,gulp-git外掛基本上可以完成所有常用的git操作,比如add、commit、push等等,還可以檢視git-log,十分方便,用法也非常簡單,比如下面是一段獲取git倉庫中tag為v1.0.0的程式碼(也可以checkout分支名):
var git = require('gulp-git');
gulp.task('checkout', function () {
git.checkout('v1.0.0', function (err) {
if (err) throw err;
});
})
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
gulp-htmlmin
就是一個壓縮html的外掛,沒什麼特別要講的,這邊也直接拿網上的一個常用配置來演示。
var htmlmin = require('gulp-htmlmin');
gulp.task('testHtmlmin', function () {
var options = {
removeComments: true,//清除HTML註釋
collapseWhitespace: true,//壓縮HTML
collapseBooleanAttributes: true,//省略布林屬性的值 <input checked="true"/> ==> <input />
removeEmptyAttributes: true,//刪除所有空格作屬性值 <input id="" /> ==> <input />
removeScriptTypeAttributes: true,//刪除<script>的type="text/javascript"
removeStyleLinkTypeAttributes: true,//刪除<style>和<link>的type="text/css"
minifyJS: true,//壓縮頁面JS
minifyCSS: true//壓縮頁面CSS
};
gulp.src('src/html/*.html')
.pipe(htmlmin(options))
.pipe(gulp.dest('dist/html'));
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
gulp-uglify
js壓縮外掛,有四個可選屬性,分別為
mangle:是否混淆變數名,預設為true(混淆),全域性變數不會被混淆,之前看到有的程式碼中的require被混淆掉了,導致程式碼錯誤,這個需要注意一下。
output:傳遞你一個物件去指定輸出的選項,個人理解是定製化的去壓縮,傳遞一個引數物件,否則執行預設的引數。(不確定)
compress:是否完全壓縮,預設為true(全壓);
preserveComments:是否保留備註,預設不保留;
本次壓縮全部都採取預設引數:
gulp.task('compress', function (done) {
return gulp.src(config.input.javascript)
.pipe(ngAnnotate({single_quotes: true}))//等下介紹
.pipe(uglify())
.pipe(concat('index_components.min.js'))//等下介紹
.pipe(gulp.dest(config.dist.basePath))
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
gulp-concat
合併程式碼,即將專案中各種JS合併成一個JS檔案。一般與壓縮連用,程式碼演示參考上方。
gulp-ng-annotate
如果不是angular框架,可以忽略。。。。
如果是的話,而且你的程式碼是這種寫法:
angular.module('someApp')
.controller('someCtrl',function ($scope) {
})
- 1
- 2
- 3
- 1
- 2
- 3
即簡寫,玩angular的應該都懂,那麼這個外掛就比較重要了。
因為按照angular官方的說法,如果簡寫的話,壓縮的時候,依賴注入很容易出問題,所以這個外掛就是幫助我們解決簡寫壓縮的問題。在打包JS的時候,往往壓縮、合併是連著用的,即參考上方‘compress’的示例程式碼。
gulp-less
一個編譯less檔案的外掛,在less編譯中,可選擇新增外掛,如【autoprefix】,自動新增CSS字首的外掛,程式碼實現為:
var less=require('gulp-less');
gulp.task('less', function () {
gulp.src(config.input.less)
.pipe(less({
plugins: [autoprefix]
}))
.pipe(minifyCss())//等下介紹
.pipe(concat('index.min.css'))
.pipe(gulp.dest(config.dist.basePath));
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
less在開發中相對於直接使用css,效率可以提升不少,具體less使用,可參照這篇文章。
如果是sass開發,就下載gulp-sass的相關外掛。
gulp-minify-css
一個壓縮css的外掛,與uglify類似,只不過一個壓縮JS,一個壓縮CSS。
可選引數為:
keepSpecialComments:是否保留特殊字首。預設為“*”,保留全部,1為保留第一條,0位移除全部,為了避免瀏覽器不相容樣式,一般選預設。
keepBreaks:是否保留換行,預設false(不保留)。
removeEmpty:是否移除空元素,預設false(不移除)。
root、relativeTo:這兩個屬性都和@import相關,貌似是指出@import的路徑(引用的less的路徑),
比如:
指明lm-library的路徑。
比較方便的做法就是直接把lm-library一起都算進壓縮編譯的路徑當中,給import的less檔案新增reference的屬性,這樣就不會對lm-library.less進行編譯了,也不會影響正常的less。
具體屬性參考:https://github.com/nfroidure/gulp-minify-css。
minimist
這個外掛,簡單來說就是從命令行當中提取引數。
開發中經常會遇到的應用場景是提供不同的引數,即動態引數,對應到gulp中,如果我們需要在命令列中手動輸入某個引數,此時就可以用minimist把他從命令列“提取”出來。
從minimist官方的文件來看,exp為這樣:
$ node example/parse.js -a beep -b boop
{ _: [], a: 'beep', b: 'boop' }
- 1
- 2
- 1
- 2
文件解釋也是一個‘-’為key,之後為value。但個人實際操作為兩個‘-’為key。可能原因是,我下的外掛不是看的文件的這個庫,或者英文太差看錯了。。。。。具體用的時候要自己注意了。
具體程式碼為:
var argv = require('minimist')(process.argv.slice(2));
gulp.task('checkout', function () {
var gitTag = argv.tag;
git.checkout(gitTag, function (err) {
if (err) throw err;
});
})
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
cmd中輸入
gulp checkout --tag v1.0.0
- 1
- 1
gulp-del
刪除目標目錄,目標檔案,演示var del=require(‘gulp-del’)
gulp.task(‘clean’,function(){
return del(config.dist.basePath);
})易理解,就不詳細介紹了。
gulp-zip
將src中的各種檔案,打成一個zip包,演示程式碼:
var zip = require('gulp-zip');
gulp.task('zip', () {
gulp.src('src/*')
.pipe(zip('zipName.zip'))
.pipe(gulp.dest('dist'));
});
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
gulp-ftp
將目標檔案,傳送至FTP伺服器,這邊有5個引數是必填的,分別為:
host:伺服器地址(必須)
port:伺服器埠(必須)
user:ftp賬戶(必須) // 如果FTP沒有訪問限制,可以不填
pass:ftp賬戶密碼(必須)// 如果FTP沒有訪問限制,可以不填
remote: 對應的伺服器檔案地址(必須)
logger:輸出檔案列表名稱,預設在專案根目錄生成檔案(可選,預設:logger.txt)
froot: 提單檔案字首(可選,預設:/usr/local/imgcache/htdocs)
exp:體驗環境地址(可選,預設null)
pro:正式環境地址(可選,預設null)
參考地址:https://github.com/sindresorhus/gulp-ftp。
演示程式碼:
gulp.task(‘ftp’, function () {
return gulp.src("dist_zip/*")
.pipe(ftp({
host: 'testHost',
port: 21,
//user: 'anonymous',
//pass:null,
remotePath: "path/"
}));
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
run-sequence
一個序列方式跑gulp任務的外掛,在實際場景中,不允許我們同時跑很多工,因為任務之間往往是相互依賴的,此時run-sequence就是一個很好的選擇,他可以讓多個任務按照寫入順序執行,同時可以控制哪些任務並行跑,哪些按照順序跑。
參考程式碼:
var runSequence = require('run-sequence');
gulp.task('publish', function (callback) {
runSequence('clean',['html', 'js','less', 'copy'],'zip_new',callback);
});
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
比如上述程式碼,執行順序為1、’clean’。2、[‘html’, ‘js’,’less’, ‘copy’]。3、’zip_new’。
當然也可以在gulp中使用依賴注入的方法。
比如:
gulp.task('two', ['one'], function() {
//任務two,會在任務one結束之後執行
});
- 1
- 2
- 3
- 1
- 2
- 3
但個人還是更喜歡,用run-sequence因為一旦依賴項變多之後,普通的注入,相互之間依賴過後,可讀性就會變差,而sequence會讓程式碼看起來更優雅,寫起來也更簡單。
上篇小結
本文上篇主要講了gulp的安裝,以及常用的外掛的介紹,gulp外掛超級多。。本文介紹的這些,主要是下篇實際用到的,下篇會使用上述介紹的所有外掛,來進行一次較完整的打包,ok,上篇作為鋪墊就到這裡。
下篇地址:請點選!