zmNgFrameWork 架構升級ng1.5和md5靜態資源快取方案【angular1.x】

weixin_34126215發表於2016-05-12

前言:

  在我前面的部落格,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.71.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,並加入方框內的程式碼。

執行在gulp.dest之前,這樣輸出的檔案將會帶上md5簽名,

執行在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

相關文章