使用 React Native 重写大型 Ionic 应用后,我们想分享一下这八个经验

2018-01-29 13:48:22 浏览数 (1)

本文的内容是关于 React Native 重写的经验分享,基于 React Native 重写 Ionic 应用Growth 过程中遇到的一些坑。

Growth 是一款专注于Web开发者成长的应用。其 1.0 和 2.0 主要使用 Ionic 实现,Ionic 1.x 的主要问题是 Angular 1.x 已经落后了。而 Ionic 2.x 则在启动的性能上不是让人满意——其实在开源方面,我是中 HDD(热闹驱动开发)的一员。

在重写的过程中,我们错误估计了其开发效率与 Ionic 2.x 是接近的,我们以为会差上个 0.2 倍左右的差距——上手新的框架的学习成本。但是实际上这个差距可能是在 0.5~1.0 倍之间,毕竟要填的坑太多了,以至于在中途的时候让人想放弃。

最后,我们花了两三个月的时间才重写完这个应用。在 APP 发布的这几天里,顺便写了篇文章分享一下经验:

  • 你遇到的问题,别人基本到遇到过
  • 版本间差异太大,导致下游配套
  • 新的组件坑更多
  • 大部分时间,你都是在重写 UI
  • 最麻烦的地方,其实是搭建环境
  • 真机才能反映问题
  • 尽早尝试 Release 0.0.1
  • 记得记录崩溃问题

幸运的是,作为一个开源应用,你可以看到这些坑是如何解决的。

你遇到的问题,别人基本到遇到过

你遇到的问题,别人基本到遇到过,要么就是你的关键词不对

这一点实际上与 React Native 无关,只是在编写应用的过程中,遇到一些奇怪的问题。而尽管我第一时间使用了 Google 来搜索,但是并不能第一时间找到合适的答案。因为在这个领域里,我算是半年新手,总会错失一些关键词。

而遗憾的是,Google 不一定能第一时间帮你解决问题,有些问题在官方的 issues 里,但是没有被索引。因此,如果 Google 不到结果,请找官方的 issues,或者源码。

如果只是一般的应用,那么你遇到的问题,大部分人也都遇到过。除非,你是在写一些原生的组件,遇到一些莫名其妙地问题。

版本间差异太大,导致下游配套

开始编写 Growth 的时候,使用的 React Native 的版本是 0.42。在Growth 3.0 里面,使用了一些长的列表,如 awesome 列表,导致性能上不是很理解。在看到 React Native 0.43 之后,便升级到了 React Native 0.44。

整个升级过程中,看上去很容易:

  1. 修改 package.json 中 react-native 的版本从 ^0.42.0 为 ^0.44.3
  2. 修改 package.json 中的 react、react-dom 等组件版本从 15.4.2 变为 16.0.0-alpha.6

然而新版本里的类型检测 prop-types,已经变成了一个独立的组件,这就意味着我需要修改所有相关的代码。要不就会遇到这样的问题:

代码语言:javascript复制
Warning: View.propTypes has been deprecated and will be removed in a future version of ReactNative. Use ViewPropTypes instead.

而,这意味着所有的第三方组件都需要修改。这并不是一件容易的事,这会导致遇到一系列的问题,如我的持续集成会在 Travis CI 出现问题。

幸运的是,我使用的原生组件比较少,因此也没有遇到一些组件不能支持新版本的问题。而对于那些库来说,他们可能是这样子的 README:

代码语言:javascript复制
if on react-native < 0.40: npm i react-native-xx@0.4if on 0.42 >= react-native >= 0.40 npm i react-native-xx@0.6if on 46 >= react-native >= 0.44 npm i react-native-xx@1.0

除了此,对于我来说,那些使用 enzyme 写的测试也出现了问题,因为 enzyme 的开发者不想支持 alpha 版本的软件。

新的组件坑更多,如文档更新不及时

当我们更新了我们的 RN 版本,我们可能会遇到文档更新不及时的问题。

如,在 Android 版里的 WebView 可以支持 allowUniversalAccessFromFileURLs,即如果我的 WebView 是通过 file 拿到的,有了这个参数就可以发起不是跨域的请求——可以解决 WebView 的跨域问题。但是在使用的时候,文档并没有更新到这方面的内容。那么,这个坑就只能自己去看源码填。好在你可以用 Command B 查看到相关的问题。

与些同时,如果你看到的文档是中文翻译,那么出于某种原因,这个坑可能会更深。

因此,作为一个 HDD(热闹驱动开发) 的程序员,如果你喜欢跳坑里,那么你应该具备深入源码的能力。否则,就不要轻易地使用最新框架,坑你不止一点点。

大部分时间,你都是在重写 UI

如果你已经习惯了 React,那么总体来说,没有多大地区别。并且,我们可以使用直接使用大量的 Node.js 的库,如 moment。

由于,这是我第二次尝试 React Native,总的来说体验比第一次好多了。先简单地作为一个小结,对于大部分人来说,他们只是在写业务功能。故而:大部分时间,你都是在重写 UI。

重写的过程中,我预期会遇到一些原生的组件问题,然而一个都没有——列表性能问题另算,即使采用了。想来这个生态已经是成熟了,

在这个过程中,尽管会遇到一些 iOS 打包的问题,Android 资源的问题。而如果你和我一样,也写过 Cordova 的插件,那么其实问题并不会太多,只是仍然会有一点。

注:在 Ionic 时代,可以用 Ionic resources 来生成 icon 和 splash 以适配不同的机型。在 RN 中,可以采用 generator-rn-toolbox 来做类似的事。

最麻烦的地方,其实是搭建环境

这一点和 Web 应用开发是类似的,在搭建 Web 应用开发环境的时候,我们需要:

  • 设计构建系统
  • 搭建持续集成
  • 完成自动化发版
  • 等等

因而,有了上面的 UI 结论后,你也熟悉了 React。对于你来说接触 RN 最大的障碍是:搭建一个开发环境。你需要 Android SDK,以及 iOS 的环境。

准备完之后, 你用官方的脚本创建了一个 hello, world,发现跑不起来,啊哈哈哈~。

最有意思的事,当前版本的 RN 不支持 Android 的包名创建。如果你开始没有取好包名,就开始填坑了,那么你就需要 react-native-rename 这样的工具来重命名包。然后继续你填坑~~

除此,作为一个追求质量的程序员,我们还需要:编写测试。除了,使用 Facebook 的 Jest 进行单元测试,React Native Test Renderer 进行界面测试,还有集成测试工具 Appium。

这些没有哪一个都会很顺利的~~。

有时候真机才能反映问题

模拟器虽然很快,但是它并不能暴露出一些问题,容易出现一些不一致。相关经历,如下所示。

尽早尝试 Release 0.0.1

我的意思是,你要早点出一个 React Native 的 MVP 版本。

由于,我日常用的手机是 Android 系统,而 React Native 的 Web 资源问题,实际上在 Android 和 iOS 上都会出现的。Android 手机上需要将资源放在: file:///android_asset/,但是对于 iOS 也需要放在 assets 目录下,否则 Release 的时候,会找不到相应的资源。

这是我在要发布新版本的时候,遇到的问题。如果是在真实开发过程中,那么这一点可能会影响你的 KPI,如果有的话;又或者会导致你加班。

记得记录崩溃问题

我在 release Growth 3.0 的早期版本 2.9.9 的时候,漏掉了一个对 Null 值的判断,结果造成了大量的闪退问题(三十几个用户)。

好在我采用的 Google Analytics 能收集崩溃信息,如下:

代码语言:javascript复制
RCTFatalException: Unhandled JS Exception: null is not an object (evaluating 'h.default.getWebView().postMessage') Trace: <redacted> growth growth <re

因此,在下一版本里便快速修复了。除此,在一些未知的机型也会出现问题,尽管是个问题,但是由于数量较少就没有在意了。

对于写原生代码来说,这几乎是必备的手段。对于 WebView 来说,并不会存在太大的崩溃问题,除非使用了原生组件。

0 人点赞