前言:
在我前面的部落格,angular專案總結——angular + browserify + gulp + bower + less 架構分享 把我開發angular的架構進行了分享,並上傳到了github https://github.com/zimv/zmNgFrameWork 。
而後我又在我的 gulp系列 裡分享了 gulp-rev:專案部署快取解決方案----gulp系列(六) ,也更新了github上gulpStart的rev分支 https://github.com/zimv/gulpStart, rev 分支 。
最近我在更新這個專案,把angular1.4.7更新到了1.5.5,關於angular的升級,我想說效能方面有提升,載入速度和流暢度都得到了提升。
比較坑的一點,我似乎安裝錯包了,之前的路由hash是用#,升級之後變成了#!,甚至控制檯會報一些不影響任何功能的錯誤。
我開啟angular.min.js,發現裡面version顯示的是 1.5.5-build.4567。於是我又重新bower安裝了1.5.5,
版本註釋資訊才變成了version:1.5.5。這個時候路由hash才是正常的#,之前的報錯也不存在了。
畢竟還是1.x,升級之後並沒有需要修改程式碼什麼的,api是相容的。關於升級1.5.5就說到這裡。
升級後,我把zmNgFrameWork 分為三個分支1.4.7、1.5.5 、1.5.5&md5-cache。如果需要md5方案,可以用1.5.5&md50cache這個分支。
md5方案:
md5的快取部署是現在比較合適和流行的解決方案。根據目前專案和架構,我覺得可以在zmNgFrameWork引入此項配置。
專案中的構建工具,我使用的是gulp,gulp-rev就是解決當前問題的外掛。
gulp-rev的基本用法這裡我就不做過多介紹,需要了解的可以先看這篇文章 gulp-rev:專案部署快取解決方案----gulp系列(六) 。
升級前,再囉嗦一下,我們最終需要達到什麼效果(以下截圖使用gulpStart裡的例項):
如圖可以看出
最終build的css和js字尾都帶有md5簽名,rev.json是儲存檔名路徑的。(我們把這一步驟叫做 ① )
最終html裡的檔名路徑要和build同步(我們把這一步驟叫做 ② )
要實現一鍵gulp就把這一切事情做好,就需要我們來配置它:
配置less:
(1) 首先還是在zmNgFrameWork npm安裝依賴gulp外掛:
npm install --save-dev gulp-rev
npm install --save-dev gulp-rev-collector
gulp-rev 來實現 步驟 ①
gulp-rev-collector 實現 步驟 ②
(2)先配置gulp的css任務,開啟less.js
require gulp-rev,並加入方框內的程式碼。
A 執行在gulp.dest之前,這樣輸出的檔案將會帶上md5簽名,
B 執行在gulp.dest之後,這樣將會輸出儲存檔名路徑的rev.json到指定資料夾,
如此一來 步驟 ① 就完成了
(3) 新建rev-collector任務,配置好revJson的資料夾路徑和html路徑,執行這個任務的時候,gulp會找到所有rev.json,與html裡的路徑匹配,最終就完成了 步驟 ②
對,這篇文章不是教大家怎麼使用gulp-rev的~ 以上只是簡單介紹配置less並大致回顧一下。
回顧:
我們再來回顧一下,zmNgFrameWork 的架構:
(1)單頁面應用,目前只有一個入口,根目錄的index.html
(2)src:
common 包含主要的less(三方庫、抽象層和通用樣式),所有圖片,和一部分js工具
modules 所有模組,模組層的less樣式,模組的template,模組的控制器、服務和指令
主模組app.js 將會依賴注入所有 modules 資料夾的子模組
(3) build:
所有圖片會被打包到build->common->img,所有css樣式最終打包為一個css,被index引用
模組的所有控制器、服務和指令打包為一個js,被index引用
主模組app.js,被index引用
繼續配置:
配置md5快取部署方案,將會讓build裡所有js和css加上md5簽名,並且更新到index.html中。
根據之前的配置,css已經Ok了,如下圖:
gulp的時候新建了一個臨時輸出檔案build:temp-build,最開始我其實是直接把rev資料夾放在build資料夾裡的,
後來覺得build裡面的所有檔案都應該是用來部署的靜態資源,不需要這些預編譯的臨時檔案。
所以就建立了temp-build作為預編譯檔案的臨時儲存。
做到這一步其實還算順利,而後我開始配置js的md5。
在配置過程中,按照之前的寫法,我發現gulp會出現報錯。
報錯的意思是當前管道流不支援。我想這是gulp-rev 不相容browserify的管道的原因。
而後我用一個新任務rev-js,把browserify打包好的js,載入到gulp管道,再執行一次輸入輸出,就能成功生成md5簽名了。
但是這個時候build裡面會變成這樣:
build裡面會存在browserify執行後的無簽名的js和md5簽名的js。
不應該在build裡面有預編譯檔案,於是也同樣把browserify生成的js放到臨時資料夾裡去。
好了 一切OK。現在 步驟 ① 全部完成。
最後再執行一次rev-collector任務,把 步驟 ① 生成的rev.json和index.html進行匹配
現在 步驟 ② 全部完成。
曲折:
看起來很簡單嘛~但是過程還有有點曲折。
特別有一件曲折的事情,我已經同步處理了gulp任務執行順序,使用gulp-sync
rev-js要操作browserify生成的檔案,所以要執行在browserify之後,下圖是cmd下gulp執行的日誌:
rev-js確實是執行在browserify之後,但是我發現rev-js並沒有輸出任何東西。
當我執行完gulp default之後,rev-js像是沒有執行一樣,什麼也沒輸出。
而後我再單獨執行一下rev-js任務,這個時候就有輸出了(因為這個時候browserify已經完全執行完畢)!
後來糾結了很久,又遇到了各種情況,又發生了各種猜測和驗證實驗。最終的結論確是:
gulp-aync無法獲取browserify的管道,也無法得知它的任務是否完成。之所以gulp日誌裡面顯示的是完成,不過是gulp預設的處理而已。
而後,我給rev-js任務加上了延遲,rev-js延遲之後,還需要給rec-collector延遲,rev-collector依賴rev-js。這樣才勉強能完成工作。
暫時沒有想到更好的辦法了。加上延遲之後,gulp-aync無法正確判斷它是否完成了任務,所以也會預設處理為完成。
不過這裡這樣使用暫時不會造成其他問題,這種處理方式實在不優雅。
當然我也想過在browserify任務裡,新增監聽事件,但是根據目前裡面的邏輯,我覺得最好不要那麼做。
如果能使node的pipe同步就好了,可以嗎?好像不行~求大牛指點!!
小結:
架構調整和升級是一件有風險,又非常有意思的事情。而最終的目的還是適應業務、提升效率、解決問題。
最後奉上zmNgFrameWork 執行後的樣子,兩個測試頁面:
gulp問題已經解決:
browserify同步問題已經得到解決,由下面評論的 @心成 解決的。如他所說,我確實沒有返回資料流,through2也幫我解決了browserify迴圈bundle的問題,總之非常感謝。
而後我還得知,他一年前gulp入門是看我部落格入門的,而如今他已經幫我解決了問題了。得多向他學習。。自己都落後了~
調整之後build目錄有所改變,之前重新命名app.js為檔名:test/test.js ,現在不重新命名: test/app.js 。
browserify管道流不被rev支援也解決了, 引入vinyl-buffer,在browserify任務後buffer()一下,詳情見最新的git