移动 App 的运行环境具备带宽不稳定,流量收费,启动速度比较重要等特色,因此混合 App 如何加载 Web 资源并非一个新问题。本文目的是总结出一种资源打包下载的思路和方案,而且提供一种打包工具。本文提到的思路只是一家之言,基本没有参考现有方案,各位方家有不一样意见欢迎留言。另外本文没有涉及到 App 内部如何加载资源的问题,这部分我会专门撰写一篇文章讨论。前端
通常来讲,Hybrid-app 对于 Web 资源下载有以下需求:node
页面开启速度要快,因此资源的下载和使用不是在同一时间进行的,有一个“预下载”的过程。git
资源不能重复下载,因此要有缓存,可是有更新的时候必须及时更新。鉴于 WebView 的缓存可控性不强,因此要有一套自定义缓存机制。github
为了节省流量加快速度,若是资源以压缩包为单位总体下载,那么资源更新时要支持增量更新。同时,对于设备端资源与最新版本相隔一个版本以上的状况,要提供全量更新。web
为了维持必定的健壮性,Web 资源在设备本地和线上应各有一份部署,能够随时切换。尤为是当设备本地缓存被删除时,能够临时切换到线上。算法
为了方便开发和部署,笔者设计了以下打包方案:npm
发布包分为四部分:json
第一,是将整个 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 格式记录了新版本和上一个版本的版本号。