前言
前端技術發展日新月異,隨着模塊化、組件化的提出,前端變得越來越復雜,靜態資源越來越多,那么對靜態資源的處理,如壓縮,合並,去掉調試信息.. 如果還是人工去處理,效率非常之低且還容易出錯,於是自動化的處理工具也就必然出現了。就像后端我們一般用maven管理項目,那么前端gulp是個不錯的選擇。
什么是gulp
是一個基於 Node.js 流、Javascript語法的快速構建前端項目並減少頻繁的 IO 操作的自動化工具。
Gulp有什么好處
易於學習使用
通過最少的API(核心.src()、.pipe()、.dest()、.watch()四個),以及代碼優於配置的策略,讓簡單的任務簡單,復雜的任務可管理。
快速構建
利用 Node.js 流的威力,你可以快速構建項目並減少頻繁的 IO 操作,處理速度傳說是grunt的兩倍。
高質量的插件
gulp社區擁有足夠滿足你需求的並且簡潔的插件,當然你也可以自己動手寫一個!
gulp API
參見 http://www.gulpjs.com.cn/docs/api/
gulp構建
1 准備工作
>安裝node客戶端
下載網址https://nodejs.org/en/download/
>全局安裝npm
npm 是 nodejs 的包管理和分發工具,全局安裝 npm install -g
>全局安裝gulp
npm install gulp --save-dev
save-dev 這個參數會將插件信息自動更新到 package.json 里,其中的 devDependencies 屬性會隨插件依賴的安裝卸載而改變
2 目錄結構
- - gulp
- - - - - -dist //生產目錄
- - - - - -src //開發目錄
- - - - - - - - - js
- - - - - - - - - css
- - - - - - - - - html
- - - - - -node_modules
- - - - - -gulpfile.js
- - - - - -package.json
3 關於package.json

mkdir gulp
cd gulp
在gulp目錄下執行 npm init 生成package.json文件
安裝相關的依賴包
npm install gulp-uglify gulp-rename gulp-concat gulp-notify .. --save-dev
另外:對於完整的 package.json (比如github上淘下來的項目), 只需對整個項目執行 npm install 即可安裝 package.json 文件中聲明的所有插件模塊
4 實現一個本地服務器
在gulpfile.js文件里,添加依賴包

定義根目錄變量

定義一個task,端口為8888,根目錄為開發目錄

在node命令窗口里執行
gulp server
出現這些說明成功了,這個時候在瀏覽器里輸入localhost:8888即可看到本地開發目錄下的文件夾。這樣一來就相當於我們傳統使用的tomcat服務啟動,就可以進行下一部的開發工作了。

5. 資源實時更新
開發中我們經常需要按f5刷新頁面開效果,那么有了livereload這個插件后,你可以徹底解放你的f5鍵了。
引入兩個依賴

創建watch task
watch()是gulp的核心API,這里實時監聽開發目錄下的html文件,同時依賴reload-dev任務,reload-dev里面實現了connet插件的reload()方法,注意:server一定要設置激活 livereload: true

因為gulp task執行的時候並不一定是按順序的,所以新建一個任務,通過sunSequence插件同步執行上面這兩個任務

node 控制台執行 gulp live,這個時候去編輯對應的html,按下保存鍵,即可看到服務reload的日志

livereload實時刷新效果圖

6. 壓縮js
同樣的,也是新建一個task,.src()方法里輸入開發環境的目錄文件,首先通過.pipe()接口執行stripDebug()方法去掉所有的調試信息,如果uglify()方法里沒有帶其他參數,默認是不保留注釋的,接着用rename插件重命名一下文件,最后通過.dest()接口輸出到生成目錄下。

同樣的在node命令窗口里執行

gulp minjs
在dist目錄就可以看到多了一個js目錄,里面的js全部已被壓縮,並且重命名為xx.min.js
7. 壓縮css
跟壓縮js一樣

node命令窗口里執行
gulp mincss
在dist目錄就可以看到多了一個css目錄,里面的css全部已被壓縮,並且重命名為xx.min.css
8. 合並js
一個頁面通常有多個js或者引入,當上產生環境的時候為了減少網絡請求,最好先將資源合並一下,gulp方便快捷的幫助我們完成了這個步驟。
可以看到,合並js是用的concat這個接口,當然首先需要引入gulp-concat

task如下,

node命令窗口里執行
gulp concatjs
最終在生產目錄下生成了一個concat文件,里面包含了一個合並的main.js
同樣的合並css步驟一樣,這里不一一敘述。
9. 靜態資源添加版本號
前端靜態資源緩存一直以來是一個梗,最簡單的方式是我們手動去資源后面添加版本號,如果資源一多,那真是個噩夢.. 幸好有gulp-rev
首先添加依賴包

建立兩個task

node窗口里執行gulp revCss 、gulp revJs后,對應的css、js目錄下分別生成了rev-manifest.json文件。
revCollector插件是根據rev-manifest.json 里面的鍵值對,再對html進行md5比較,最終將有變化的html進行版本更新
建立處理html task
運行gulp revHtml后,會發現生產目錄下的html文件引用的js/css自動添加的版本后綴
當然,后續更改了相關js/css后,需要再執行revCss和revJs,所以這里也通過一個集合task有序的執行上面三個任務

效果圖

有一點需要注意,我們通常期望添加的版本號是這樣子

可是gulp-rev默認類似是這樣 common911965ed05.js,是再重新生成了一個js文件,隨着越來越多的版本更新,文件越來越多,顯然不合適,那么為了達到期望的效果,需要對其源碼做如下相關的修改:
打開node_modules\gulp-rev\index.js 第144行 manifest[originalFile] = revisionedFile; 更新為: manifest[originalFile] = originalFile + '?v=' + file.revHash;
打開nodemodules\gulp-rev\nodemodules\rev-path\index.js 10行 return filename + '-' + hash + ext; 更新為: return filename + ext;
打開node_modules\gulp-rev-collector\index.js 31行 if ( !_.isString(json[key]) || path.basename(json[key]).replace(new RegExp( opts.revSuffix ), '' ) !== path.basename(key) ) { 更新為: if ( !_.isString(json[key]) || path.basename(json[key]).split('?')[0] !== path.basename(key) ) {
