綜述
移動 App 的執行環境具有頻寬不穩定,流量收費,啟動速度比較重要等特點,所以混合 App 如何載入 Web 資源並不是一個新問題。本文目的是總結出一種資源打包下載的思路和方案,並且提供一種打包工具。本文提到的思路只是一家之言,基本沒有參考現有方案,各位方家有不同意見歡迎留言。另外本文沒有涉及到 App 內部如何載入資源的問題,這部分我會專門撰寫一篇文章討論。
需求梳理
一般來說,Hybrid-app 對於 Web 資源下載有如下需求:
-
頁面開啟速度要快,所以資源的下載和使用不是在同一時間進行的,有一個“預下載”的過程。
-
資源不能重複下載,所以要有快取,但是有更新的時候必須及時更新。鑑於 WebView 的快取可控性不強,所以要有一套自定義快取機制。
-
為了節省流量加快速度,如果資源以壓縮包為單位整體下載,那麼資源更新時要支援增量更新。同時,對於裝置端資源與最新版本相隔一個版本以上的情況,要提供全量更新。
-
為了維持一定的健壯性,Web 資源在裝置本地和線上應各有一份部署,可以隨時切換。尤其是當裝置本地快取被刪除時,可以臨時切換到線上。
資源打包方案
為了方便開發和部署,筆者設計瞭如下打包方案:
釋出包分為四部分:
第一,是將整個 Web 資源目錄打成一個壓縮包(bundle.zip)。
第二,基於上一個版本,構建一個最新版本的增量壓縮包(update.zip)。為了簡化開發,我使用了檔案級的 diff 演算法——也就是說,對比兩個版本的程式目錄,將新增和有改動的檔案連帶目錄結構打成壓縮包。對於新版本中被刪除的檔案,本方案忽略,因為 Web 前端程式中多一個檔案並不會有任何影響。
第三,整個 Web 資源目錄以目錄的形式存在於釋出包中,目錄名為 /web,當裝置端本地資源不能用時,可以直接使用 Web 目錄中的線上資源。另外,為了方便單步除錯,除錯版 App 也使用線上資源。
第四,版本資訊檔案 update.json,本次釋出的版本號、上一個版本號,以及釋出時間存在於這個檔案中,供 App 定時下載檢查。update.json 格式如下:
{"releaseTime":"160530161454","version":9601,"lastVersion":9596}
以上就是整個釋出目錄結構,將這個目錄整體上傳到後端雲端儲存,提供下載連結,App 即可實現下載更新等功能。在暫時不用考慮 App 版本和 Web 版本配合問題的前提下,為了方便 App 開發,筆者使用了恆定不變的 URL,比如:
http://www.url_prefix.com/some_folder/webapp/app_name/update.json
http://www.url_prefix.com/some_folder/webapp/app_name/bundle.zip
http://www.url_prefix.com/some_folder/webapp/app_name/update.zip
http://www.url_prefix.com/some_folder/webapp/app_name/web/
這樣做的好處是設計 App 時約定好 URL,這些 URL 就不會變了,App 只要定時拉取 update.json 檢查版本,該更新更新即可,Web 資源釋出時只要替換掉相應的檔案即可,流程比較簡化。這樣的方案導致線上只有一個版本,所以如果你的專案中不同版本 App 需要不同版本的 Web 資源配合,那麼你就不能使用這種方式。
資源打包工具
方案確定後,我們還需要一個打包工具,方便開發人員釋出資源。顯然,這個工具不能要求開發人員自己保留老版本目錄,所以我們需要依託於版本控制工具。筆者使用 node.js 開發了一個基於 svn 的命令列打包工具 packr:
packr 的原理很簡單:由釋出人員確定釋出專案的 svn 地址、本次要釋出的 svn 版本號,以及上次釋出的 svn 版本號,packr 會按照上面的方案將資源打成一個釋出包。如果你用 git 的話,可以簡單改一下底層的版本控制元件。這個工具本身和前端開發無關,你可使用它為任何專案打發布包。
packr 的使用說明如下:
靜態資源打包工具(packr)使用說明
綜述
packr 是專為移動 app 混合開發設計的 web 靜態資源打包工具。
packr 通過比較兩個 svn 版本的區別(目前還不支援
git),將靜態資源專案打包為全量更新包、增量更新包,以及線上資源目錄,同時生成版本資訊 update.json。執行環境
packr 基於 nodejs 實現,使用前請先安裝 nodejs。
packr 依賴的 npm 模組需要聯網安裝,請確保連入網際網路。
packr 依賴 svn 命令列工具,使用前請安裝 svn 並確保環境變數 Path 中有相關目錄。
packr 沒有 svn 賬戶設定入口,使用前請確保 svn 已經儲存了可用的賬戶名。
packr 為命令列工具,使用前請確保環境變數 Path 中有 packr 根目錄。
執行前準備
假設 packr 根目錄為 /usr/local/packr
cd /usr/local/packr npm install
命令引數
packr 命令格式如下:
packr -p=${prefix} -c=${currentVersion} -l=${lastVersion} -r=${repositoryURL}
其中:
prefix 為輸出目錄,如果不設定,則輸出於當前目錄。
currentVersion 為當前釋出版本的 svn 版本號。
lastVersion 為上一個版本的 svn 版本號。
repositoryURL 為 svn 版本庫地址。
輸出
packr 輸出為一個 zip 壓縮包,其中有如下檔案或目錄:
bundle.zip 新發布版本的全量更新包。
patch.zip 增量更新包,其中有新增和改動過的檔案。
web 線上資源目錄,供客戶端或瀏覽器在不使用快取時直接訪問。
update.json 版本資訊檔案,其中以 json 格式記錄了新版本和上一個版本的版本號。