React Native 不是未来

23-01-01 banq

2017 年,我们的移动应用程序过渡到 React Native,将我们的代码库总数减少到两个。有一段时间,这感觉就像天堂。现在每当我们想引入一个新特性,比如加密的图像和文件,我们都需要“只”写两次——多么美妙、方便的安排,对吧?大错特错。

当然,最大限度地使用库,并确保你不会重复编写关键的业务逻辑。然而,在某些时候,我们达到了这种方法的极限,别无选择,只能用C语言编写低级的流媒体加密函数,因为我们的web加密库在移动端无法重复使用。

但是,即使假设你已经最大限度地使用了共享库,用一个小团队为两个代码库协调功能仍然是加倍的努力。我们的移动平台和Web平台有不同的问题,在不同的时间线上工作。一个存在于移动平台但不存在于网络平台的错误,需要两天时间来修复,这意味着Web和移动平台一直处于不同的波长。要让Web和移动团队 "同步 "进行新功能的开发是一个持续的挑战。此外,Web上的建设通常比移动端快得多,所以移动端总是落后。

在不使用大量第三方库的情况下,也没有切实可行的方法来构建React Native:
React Native的包是他们自己的特殊品种的怪物,因为包的作者将是写两次代码的人:一次用于iOS,一次用于Android(当然还有JavaScript包装器)。其结果是,在已经存在的依赖第三方库的弊端之上,库的放弃和稳定性问题也急剧增加。此外,保持你的库与你当前版本的React Native同步(React Native是出了名的难以保持更新),这本身就是一个噩梦。

在某种程度上,我们已经看够了,我们开始梦想一个更好的世界:但不能是现在这样的。两个代码库。
我们开始幻想能够只写一次代码:
想象一下,我们可以多快地交付?想象一下开发者的生产力和快乐;想象一下,我们梦想着一个功能,并且不会因为 "啊,对了,我们还得把它写到手机上 "而感到失望,然后因为加倍努力的不切实际而完全放弃这个功能。
一个单一代码库的功能已经足够努力了。所以我们就去努力实现不可能的事情。

一个代码库就能统治一切
只是事实证明,这并非不可能。当我们完成过渡时,我们问自己为什么不早点这样做。
今天,Standard Notes只有一个代码库。
我们的移动应用就是我们的Web应用,可以访问原生的移动功能,而且它的运行就像一个梦。
它的特点是与我们的桌面应用1:1的功能相同,这在我们的旧应用中是不可能的。它可以访问本地移动钥匙串、生物识别、本地存储、摄像头等。

我们是如何做到的?
其实很简单:在web世界和移动原生世界之间架起一座桥梁:
我们的新移动应用仍然使用React Native,但实际上只有一个组件:一个渲染webview的函数。
这个webview通过postMessage桥在web-land和native-land之间进行信息传递。当web-land想要访问设备的钥匙串时,它向native-land发送一个消息,而native-land则以一个原始值作为回应。

不过,无论是native-land还是web-land都不需要考虑 "消息":它们只是函数调用。
Web-land不知道它的函数调用在幕后被转换为postMessage调用。Web也在使用await进行响应,就像它使用其他异步函数一样。
这不是一个技术性的帖子,但在高层次上,我们的架构包括每个平台只需要为应用程序实例提供一个 "设备接口",有了这个接口,一个应用程序可以在任何平台上运行,甚至是命令行。设备接口提供对设备API的访问,如数据库、钥匙串或摄像头。

构建移动设备的更好方法
不要误会我的意思:React Native 有很多值得喜爱的地方。它的社区和包生态系统充满活力,可能比许多类似的库更活跃。但是,如果您发现两个代码库太多了,也不必像这样。您不必从头开始将 Web 应用程序 UI 重写为 React Native。相反,只需使用 RN 作为从 Web 应用程序核心访问本机系统功能的桥梁。您的用户将无法区分。就我们而言,据我们估计,我们的新移动应用程序比我们永远落后的旧应用程序好 10 倍。

如果你今天开始,你可以采用与我们类似的方法,或者看看像Capacitor这样的库,它们做的事情非常相似,缺点是没有像 React Native 一样丰富的第三方包生态系统。