公司用的ionic混合开发,用到一个cordova热更新插件cordova-hot-code-push-plugin,突然发现在我接手之后热更新不好使了,于是在ios代码中打断点查找错误,发现在下载服务器代码的时候下载失败,报错-4,于是开始查找下载失败原因。
先说一下这个插件的原理:
首先需要在根目录里配置一个cordova-hcp.json的文件,文件中写明
```
{
"autogenerated": true,
"content_url": "https://XXX",
"update": "start"
}
```
以及在 config.xml中配置
通过执行 cordova-hcp build,在www文件下生成chcp.json和chcp.manifest两个必要文件
chcp.json例子
{
"autogenerated": true,
"content_url": "https://XXX",
"update": "start",
"release": "2019.01.18-13.47.24"
}
其他属性可以自己加,其中必要的是release和content_url,release描述的是web项目的版本号,一般是生成chcp.json的时间,插件更新就是通过比较本地的release和服务器上的release是否相同,不相同则根据chcp.manifest中记录的变化下载服务器上的代码,并进行替换
chcp.manifest例子
{
"file": "build/main.css",
"hash": "3289b8e7a436982f25d5c4fb92bf5e86"
},
{
"file": "build/main.js",
"hash": "00428b26fbf2fe186c107b0e83f277f1"
},
file: 相对于 www 目录的文件路径
hash: 文件的 MD5 哈希值,用于判断文件是否发生变更
热更新流程
① 应用启动
② 热更新插件初始化,并在后台加载更新模块 (update loader)
③ 更新模块 (update loader) 从 Cordova 项目配置 config.xml 文件中获取 config-file (热更新插件配置文件 chcp.json 的加载路径),然后加载配置文件 chcp.json,获取其中的 release 版本号,对比当前的版本号,若二者不同,说明有新版本,执行下一步
④ 更新模块 (update loader) 从 chcp.json 配置文件中获取 content_url 作为 base url,然后加载 chcp.manifest 文件,或者新版本文件变更信息
⑤ 更新模块 (update loader) 根据 content_url 作为 base url,下载所有变更、新增文件
⑥ 如果一切顺利, 更新模块 (update loader) 发送通知,该更新已准备好进行安装
⑦ 安装更新,应用重定向到新版本页面
说完整个原理,说一下我遇到的问题,我应该是在上面的第5步下载文件的时候出错,error codeshi -4,查看文档https://github.com/nordnet/cordova-hot-code-push/wiki/Error-codes,-4就是从服务器下载更新/新文件失败,应该是文件的哈希值不匹配,到这里我就懵圈了, chcp.manifest 不就是记录文件的变化的嘛,文件发生变化哈希值就是不一样的呀,不一样怎么还报错了呢,于是陷入了死循环。。。。直到被我们领导点醒,应该是服务器那端文件生成的哈希值和我收到的文件的哈希值不匹配,哈希值是用来检查文件内容在传输过程中是否被别人篡改,于是恍然大悟。。
查找了一番发现,是main.js文件的问题,在执行 cordova-hcp build生成chcp.manifest时文件main.js里的内容是压缩的,而在执行这个命令后我又执行了ionic cordova build android,执行之后main.js的内容是没有压缩,而chcp.manifest文件中记录的是压缩的文件内容,因此在检查哈希值的时候匹配不上导致下载失败,尴尬了。。。解决的办法就是在执行ionic cordova build android时加上--prod,让执行之后的main.js也是压缩的能跟chcp.manifest对上就可以了。
参考文章:
https://objcer.com/2017/06/18/cordova-hot-code-push/