开篇之前,先讲一个自己开发中的一个小插曲:
今天周日,iOS版 App 周一提交,周三审核通过上架,很给力.不过,中午11:30的时候,运营就反应某个页面有一个很明显的问题,页面没法拉到底部,部分信息显示不全;那个页面是基于react-native写的,项目中本身已经有了热更新的相关机制;原因很简单,13:00左右,解决问题,发了一个补丁,测试环境自测完毕;补丁发给Leader,他可以提交到线上;出去吃饭,13:00 回来午休;14:00,Leader回到工位,补丁提交到线上;确认补丁生效,问题解决.
不要吐槽说,流程可以更优化,解决的问题更快,这涉及到另一个话题,改日有心情再聊.
如果按照没有热更新能力的解决流程,大致会是: 11:30 发现问题,13:00 解决,确认测试环境生效;生成测试包,上传 提交;人品好的话,可以走紧急审核;3~5天后,问题修复.3~5天的审核期,有人认为很长,有人早已习以为常.
小插曲而已,看看就好.我只是想让大家明白,react-native本身,可能对你的业务,确实是一个很有意义的工具,仅此而已.许多人,也是认同 react-native 的价值的,但是可能并没有在自己的项目中应用,而没有应用的原因,相对一部分原因,是很难驾驭.从我目前的实践来看,没有一个能够同时自由驾驭Native和react栈的技术人员存在,一个技术组是很难有可能把react-native应用起来的.因为前期,必须有 native 技术栈的人,去填补一些可能用react比较难实现的功能;中后期,又必须 有 react 技术栈的人,来深入地利用react本身的技术栈,来提高开发效率,比如redux的应用等.
类似的例子,我是见过一些,有死在 node 环境配置的,有卡在 native 已有应用无法集成的,当然,也有卡在不知道 如何下手使用 react-native的 的热更新能力的.
热更新,本身机制的设计,网上讨论的也是有一些,一个最简化的模型是: react-native 是基于 main.bundle 加载的; main.bundle 本身是一个文件夹;每次打开app,都去查看有无最新的 main.bundle,有就下载更新本地文件即可.blablalba…..会涉及到许多细节问题,但我相信,一个搞Native开发的人,是都可以独立解决的.
今天,要说的问题是, main.bundle 里,是包含所有的资源文件的,现在发补丁,我是整个 把最新的 完整的 main.bundle 发出去了,本身压缩后,不到 1M,和一个大图片也差不多,基本用户无感;但我现在是需要逐步把原生的部分代码,逐渐迁移到 react 来的,其中的比较基础也比较关键的一步是,把 原先Native代码中的资源文件,迁移到 main.bundle 里,使用 main.bundle 管理.
好吧,不要又吐槽我说, main.bundle 里,是不会打包未使用的图片的; 我的确是,手动把图片放到 main.bundle 里的,里面新建个 native 文件夹,用于放置 native 代码需要的一些资源,这样 native 代码,也可以部分使用 热更新的逻辑了.现在项目中,热更新的逻辑有两部分: JSPatch 和 react-native,我是通过 一个 补丁类型字段来区分的.如果为 native 和 react单独分开设计 热更新机制,想想都心累–或者说,有点太懒,有些代码,还不想去动.–别怪我话多,这是一个很有价值的策略,如果你也是基于Native来混编react-native的话,或许有种茅塞顿开或者英雄所见略同的感觉,虽然我只在iOS上试验过.
有点跑题了,再次试图回归正题.说到两个main.bundle 比较diff出一个差集,网上讨论的很多,大家搜下,勉强多少有些可以借鉴的.index.jsbundle文件本身的diff,我暂时不考虑,感觉没必要,压缩后 只有 300 k的东西,还不值得我去改热更新的实现代码,而且 jsbundle 本身的机制一直在变,比如最近的 jsbundle 都有个了一个对应的 index.jsbundle.meta 文件,原来的设计,可能是有问题的;我今天要讨论的只是,文件级别的 对比操作–简单说,就是 找到两个文件夹中不相同的文件,放到第三个文件夹中,就这样.
有人说,可以比较 md5 什么的–当然也是可以的;但是,我现在不想去知道这个原理,或者说,原理我是知道的,我不想去实现这段代码,没写过,谁知道有什么坑呢?比如,文件目录结构如何保留什么的.我想知道的是,有没有一种简单的方法,一个ctrl+c ctrl+v,就可以直接得到答案问题的方法?
当然是有的, shell 脚本嘛,什么不可以搞,如下:
rsync -aHxv --progress --compare-dest=$(pwd)/main_old.bundle/ $(pwd)/main_new.bundle/ $(pwd)/main.bundle/
find $(pwd)/main.bundle/ -type d -empty -delete
好吧,脚本本身确实不难,只是我自己刚好需要用到,google出来,再分享给大家而已.我相信,一个深度使用 react-native 到项目中,并且比较依赖其可以热更新特性的人,是肯定有这个需求的;而且,我也知道,他们相当一部分,要么不能准确地问出问题,要么傻傻地自己去写 文件夹对比的代码…我不能说那不对,我想说的是: 编程这种东西, 多学点总是好的.此处奉上原始google参考链接,与原始答案有细微不同,懂shell的人,一眼就看的出来,不懂的,估计就算搜到答案,也有很大几率弄不出来结果.链接奉上: http://serverfault.com/questions/506005/compare-2-directories-and-copy-differences-in-a-3rd-directory http://unix.stackexchange.com/questions/24134/remove-empty-directory-trees-removing-as-many-directories-as-possible-but-no-fi
还有就是,react-native 我很看好它,虽然它很有可能将来把我自己的饭碗给砸了.大势所趋,没办法;浪潮之下,要么开车,要么被压平成路,硬着头皮上吧,万一大家以后都用这个搞了呢…