写点什么

React Native 优先的多端统一化方案

  • 2020-12-27
  • 本文字数:3096 字

    阅读完需:约 10 分钟

React Native 优先的多端统一化方案

一、方案背景


长期以来 APP、H5、小程序等各个端的定位和发展历程都不一样,各端技术栈差异性也较大,基于成本和效率考虑并不追求各端一致性,结果就是各端真的就渐行渐远了。


移动端增量红利越来越少的情况下,产品这边逐渐追求各端的产品体验一致性,多端同时上的需求越来越多,但是由于技术上割裂较大,工时基本都会按端加倍,开发成本奇高,迫切的需要一套减少多端开发成本的方案。


二、方案调研


开始之前我们对业界现有的一些跨端方案进行了简单的调研和了解。



通过对比目前的多端开发主要有以下几个大方向:


  1. 对 IOS 和 ADR 的 native 端 APP 的适配

  2. 中国特色的针对各小程序平台的适配

  3. 都希望可以兼顾到对 H5 的转换


而实现方向上看起来五花八门,但总体思路上主要还是两个大方向:


  1. 提供自定义 DSL 静态编译转化成目标源代码(运行体验好)

  2. 运行时适配兼容(开发体验好)


这两种方式的优缺点都非常明显(相关框架和方案对比文章都较多,可自行详细了解)。目前社区基本都想在运行上努力,开发当然要自己爽啊,实际体验下来除了在微信小程序上性能问题较大之外,也没啥大毛病。


taro 作为较早的多端方案,适配性和兼容性都不错,自定义 DSL,JSX 由于其转译复杂性限制也较多。


taro-next 和 remax 都是运行时适配的方案,而 remax 的口号是 “使用真正的 react 构建小程序” (好好体会,后面要考)。


Chameleon 是号称兼容性和运行效率上都比较高的,编译和运行时适配的技术都用到了,不过由于他是支持的 weex 就没做深入尝试了。


其他像 alita,KBone,react-native-web 都在自己的小领域内能较好的运行。


三、方案介绍


1、解决思路


调研完发现上面的方案其实并不能很好的直接解决我们的问题:


Qunar 整体技术栈以 react 为主,几年前已将 APP 整体迁移到 RN 技术栈上,解决了 IOS 和 ADR 的 2 端问题。APP 的体验和开发是最重要的,不能为了多端用新的 DSL 语法来限制对 RN 技术的使用,降低 RN 的性能和开发体验。基于现状,其实我们想要的是:能直接将 RN 转换到 H5 和各小程序平台的多端方案,可惜没有。


不能直接找到一次将 RN 运行到多端的方案,其实如果能分别解决 RN 到 H5 和 RN 到小程序的问题也是能达到目标的,分析前面的跨端方案还是有一定可行性的。



2、RN 到 H5


react-native-web 是 Twitter 开源的可将 RN 代码运行在 H5 上的方案,而且他们 H5 端的官网就是直接用 RN 转出来的,自信到连自己主站都敢用的方案肯定是要尝试一下的,于是出去看了下线上效果:



发现保真度和体验还可以,对该方案的实现原理进行了解之后,觉得 H5 可行,后续到小程序的方案也深受启发。


3、react-native-web 原理


先看一行 RN 代码:



再看 react-native-web 的源代码:



使用方式:



他的方案其实挺简单粗暴的,把 RN 的组件和 API 都用 H5 实现适配一遍,适配其行为和默认样式,在打包的时候使用 webpack 的别名机制将用到的组件替换成 react-native-web 里的对应组件。


简单的方案实现起来工作量还是挺大的,所以 react-native-web 里也大量的直接使用了 react-native 的源代码,谁让他们都是 JS 呢。


既然到 H5 可以这么简单粗暴,那到小程序是否可以呢?


4、RN 到小程序


我们知道小程序都有一套自己的 DSL 语言,而且与常规前端不同的是他将逻辑层和视图层完全隔离在了两个线程里,两边数据和对象都不共享,只能通过 Native 层来传递数据通讯。


RN 广义上来说也是一样的双线程机制,不过 RN 的渲染是用的 native,小程序用的是 webkit。


RN 是完全基于 React 语言的,比小程序的 DSL 要灵活复杂得多,要把 React 语法和 JSX 编译成一个子集的话困难性还是很大的。


这个时候我们想到了 remax:使用真正的 react 构建小程序。


如果我们像 react-native-web 一样,把 react-native 组件用 remax 来实现一遍,是不是就可以将 RN 运行到小程序上了呢?


5、remax 实现原理


这部分网上有详细的原理介绍,这里只简单说一下:


react 在内部做完 VirtualDOM 的更新后最终都要调用宿主环境的更新方法(add remove)来更新界面,为了更好地对接各个平台 react 提供了 react-reconciler 库来传入真正宿主元素的更新方法(HostConfig)。基于这个库可以方便的实现出 ReactDOM、RN 等 react 渲染层。remax 就是基于该组件实现的一个 react 的渲染层,不过小程序里不能直接去更新界面,所以 reamx 会把更新收集起来,然后生成一个更新数据通过小程序的 setData 触发渲染层的更新。然后在小程序渲染层实现一个通用模板来渲染这些数据。


这个方案带来的好处和缺点,在微信小程序里的性能限制下面 remax 和 taro next 的原理介绍里都讲得很透彻,这里就不在复述了。


remax 原理介绍:


https://juejin.im/post/6844904131157557262


taro next 也采用了类似的原理:


https://juejin.im/post/6844904036743774216


6、RN 到小程序组件库


基本原理同 react-natvie-web,只不过在对 RN 组件的具体实现上采用直接使用对接到 remax 组件上的方式。看代码例子的话目录结构等是不是都和 react-native-web 很像。



四、最终多端方案


最终经过调研和尝试,我们选择了按平台用不同的方案进行转换的方案:


  1. H5 上直接用 react-native-web 进行转换

  2. 到小程序端使用 reamx 组件实现一套 RN 的组件库,借用 remax 来适配到多端

  3. 借助 webpack 的特性来实现针对不同平台的打包




qrn-mirror 就是前面提到的针对 RN 组件到小程序的组件适配库,使用 remax 实现。


我们的主要工作量集中在 qrn-mirror 层对 RN 组件的适配,借助现有开源方案小成本的实现了这个事情。


当然在实现小程序组件的时候我们才理解 remax 只说了 “使用真正的 react 构建小程序” , 从来没说过支持多端一致的,这差别你体会体会……不过幸运的是 remax 确实也通过 remax/one 提供了多个多端兼容的基础组件。当然我们最终还是选择继续使用 remax 来开发了组件库,谁让他是完整支持 react 的呢,另一个我们也不追求一次把所有小程序端都适配了。


五、多端动态方案


前面实现了将 RN 代码在多端运行的机制,但是在实际迁移中并不是所有的 RN 特性小程序和 H5 都能支持,产品和交互本身也有差异,这时候还是需要对各端做差异化和降级的。


如何做到多态其实 webpack 都已经替我们做好了,我们只需要用和定好规范就好了。


1、文件内小范围的多态


借助 webpack 的 tree shaking 和 webpack.DefinePlugin 插件,可实现按端执行逻辑且不出现冗余代码。



2、文件组件级别的多态


受益于 react 良好的组件化机制,只要我们按文件导出同样 API 的 react 组件,可以无缝的针对多端做替换。remax 也能做到自动识别小程序的原生组件。而我们只需要根据平台动态修改 webpack 查找文件后缀的优先级顺序就好了。



最终打包时在 H5 端使用 index.web.js 内导出的兼容组件,其他端用 index.js 里导出的组件。


六、效果展示


最终我们实现了一个开发工具,在规范 RN 工程目录结构的情况下可以一键转换出 H5 和小程序的版本。目前已经在低价机票,机票订单详情,公共订单列表等项目中进行了应用。后续也希望在主流程和更多新项目中直接使用。



七、后续计划


这次我们只分享了整个方案的大致思路,后续会逐步分享一些我们在实践过程中踩的一些坑和应对方案。


  1. 第三方不侵入打包过程介绍

  2. 和 nanachi 的环境整合方案

  3. react,react-native-web, remax 的版本对应和锁定问题

  4. 小程序不支持全局 global 对象的问题

  5. 小程序中 RN 动画解决方案

  6. 小程序中的渲染性能优化

  7. stylesheet 样式解决方案

  8. 多平台工程的工程结构限制

  9. 库 Size 大小分析优化过程和解决方案



头图:Unsplash

作者:冯地木

原文React Native 优先的多端统一化方案

来源:Qunar 技术沙龙 - 微信公众号 [ID:QunarTL]

转载:著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

2020-12-27 22:373624

评论

发布
暂无评论
发现更多内容

MySQL8.0.32的安装与配置

Java你猿哥

Java MySQL ssm Java工程师

Rust-Shyper:基于 Rust 语言的高可靠、开源嵌入式 Hypervisor

openEuler

Linux rust 操作系统 虚拟机 嵌入式

分布式计算技术(上):经典计算框架MapReduce、Spark 解析

星环科技

分布式计算

分布式计算技术(下):Impala、Apache Flink、星环Slipstream

星环科技

分布式计算 Slipstream

竞争焦点转向数智底座 用友能否再引领

用友BIP

用友iuap 用友技术大会 升级企业数智化底座

阿里十年资深码农共享SpringCloud微服务架构实战文档

Java你猿哥

微服务架构 Spring Cloud ssm 架构设计 架构师

分布式场景下,Apache YARN、Google Kubernetes 如何解决资源管理问题?

星环科技

资源管理 Apache YARN

如何创造数据资产价值?如何对内赋能业务运营,对外创造市场价值?

星环科技

数据资产 数据要素流通

分布式技术剖析

星环科技

分布式

基于公共信箱的全量消息实现

百度Geek说

大数据 即时通讯 企业号 4 月 PK 榜 公共信箱

数栈V6.0全新产品矩阵发布,数据底座 EasyMR 焕新升级

袋鼠云数栈

大数据 基础软件 数字化转型

阿里RocketMQ创始人首次分享出这份RocketMQ技术内幕神级架构手册

Java RocketMQ 消息队列 消息中间件

权威学者、企业CFO荟聚上海国家会计学院,共探「智能会计 价值财务」

用友BIP

智能会计 价值财务 用友智能财务 业财融合

分布式存储技术(上):HDFS 与 Ceph的架构原理、特性、优缺点解析

星环科技

hdfs 分布式存储 Ceph

自动化回归测试平台 AREX 0.2.8 版本正式发布!

AREX 中文社区

自动化测试 接口测试 回归测试

SysCare:为您的操作系统保驾护航

openEuler

Linux 操作系统 openEuler 内核 热补丁

度量分析开源社区健康度,助力企业开源生态健康发展——华为开源管理中心王晔晖

开源雨林

开源治理 OSPO OSS Compass CHAOSS

电信及互联网行业数据安全内控审计建设实践 | 盾见

极盾科技

数据安全

分布式存储技术(下):宽表存储与全文搜索引擎的架构原理、特性、优缺点解析

星环科技

分布式 全文搜索

代码重构:面向单元测试

阿里技术

星环科技自研技术,加速大数据从持久化、统一化、资产化、业务化到生态化

星环科技

大数据

分析型数据库:MPP 数据库的概念、技术架构与未来发展方向

星环科技

MPP数据库

anyRTC快对讲融合通信指挥调度平台

anyRTC开发者

音视频 融合通信 快对讲 视频监控 综合调度

这一秒,困扰了程序员 50 年!

Java你猿哥

Java 程序员 ssm 计算机

从入门到精通,超详细的程序员Java学习路线指南

Java你猿哥

Java 数据库 Web ssm 死磕 Java 基础

iSulad+Kuasar:管理面资源消耗锐减 99%的新一代统一容器运行时解决方案

openEuler

Linux 容器 云原生 操作系统 Kubernetes Serverless

校企共建|阿里云与西安电子科技大学人才培养交流会顺利举行

云布道师

校企合作

企业数据平台建设的基石:构建统一的数据存算能力

星环科技

存算能力

Github星标120k!这份阿里独有的高并发实战笔记太强了!

Java redis zookeeper Netty 高并发

React Native 优先的多端统一化方案_语言 & 开发_Qunar技术沙龙_InfoQ精选文章