16

开源 | Taro 3 支持 React Native

 3 years ago
source link: https://mp.weixin.qq.com/s?__biz=MzI1NDc5MzIxMw%3D%3D&%3Bmid=2247490560&%3Bidx=1&%3Bsn=2ff767e76178f68390eb660d1780d4ce
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

ZFF7jq7.gif!mobile

随着 58 业务版图不断壮大,带来的技术挑战是怎么在业务融合的过程中避免重复建设,提升开发以及多端落地效率,集团孵化了内部项目 58-rn,目前为止已经在组件化、开发流程优化、发布平台建设以及线上监控预警等环节拥有一定积累。

同时,Taro 是一款优秀的跨端开发框架,在 58 众多产品线中都有使用,例如二手房、新房等。Taro 3 发布后暂不支持 React-Native 平台,于是我们向社区提交了一份实现草案,希望把 58 在 React-Native 上的技术积累分享到社区,同时也从社区对 Taro 的共建上获益。

euYZFv6.gif!mobile

项目特性

  1. 更纯粹的 React Native 支持,社区生态对接更加简便;

  2. 更好的 source-map 支持,开发调试体验大幅提升;

  3. 更加完善的样式写法支持;

  4. 与 Taro 3 React 框架一致的运行时标准;

  5. 更丰富的 API 与组件,原生依赖支持按需引入;

  6. 高稳定高性能,源码 TypeScript 开发、单元测试覆盖全;

核心关注点

鉴于 Taro 良好的可扩展架构演化,适配 React-Native 变得更加容易。本文总结一些我们在设计上的新思考,希望能够抛砖引玉。

Webpack or Metro?

Taro 目前的核心流程如下所示:

maEZRvJ.png!mobile(出处:https://nervjs.github.io/taro/blog/2020-07-01-taro-3-0-0/)

我们做出了一点小改变,采用 metro 直接生成 bundle 文件;这与 WEB 端的处理类似。广义上理解,针对小程序各端的处理也基本类似,只不过中间多了一步:先编译成目标平台的代码,然后再用小程序 IDE 编译发布。当然它与前两者还是有些差异:目标平台的中间代码包含 Taro 运行时,调试起来并不是非常直观;而前两者直接生成最终打包资源,所以天然地支持 source-map 。这一改变带来的好处:

  1. 更好支持项目调试;打包资源中的运行时错误通过 source-map 直接与项目工程代码对应,定位问题更直观;

  2. Metro 更加贴合 React-Native 的打包场景:通过多级缓存以及 hasteFS 让打包速度更快;

  3. React-Native 社区基于 Metro 的打包优化方案对接起来更容易;

6RVfim.gif!mobile

现在情况变成了:WEB 和 React-Native 直接打包;小程序则使用端平台插件机制进行扩展,生成目标平台代码,需要二次编译才能发布。框架图后半部分更新后看起来像这样:

QviIf2q.png!mobile

“零“ 成本适配 React-Native 平台

在讨论方案之初,我们的目标之一:Taro3 项目只要升级框架版本就可以作为 React-Native 项目运行起来,无需对 Taro 项目模板进行任何修改;这保证了业务逻辑代码以非常低的成本在 React-Native 端进行复用。

当然我们没法保证应用的运行效果完全符合预期;例如 CSS 标准中,子元素可以继承其父元素的样式,这在 React-Native 中并不适用;为此,我们支持编写针对React-Native 平台的专属样式。

另外,React-Native 的样式定义是 CSS 标准的子集,所以我们在编译时会对 React-Native 不支持的样式给出提示以及修复建议;这样开发者就可以逐渐熟练编写兼容多端的样式。最后,如果开发者仍然希望使用 React-Native/cli 的话,只需要修改 metro 配置就可以自由切换。目前,仅支持基于 React 编写的应用“零”成本扩展到 React-Native 端。

qiYnqiN.jpg!mobile

促进社区融合

目前 Taro 和 React-Native 社区都主要以 WEB 开发者为主,但是侧重点略有不同。Taro 主打 WEB 和小程序的融合,兼容多个应用开发框架,更偏向于小程序生态;React-Native 主打 React 生态,降低学习成本(learn once, write anywhere)。

Taro 1 和 2 做了大量工作来支持 React-Native,但是在开发体验以及 API、组件适配程度上还需要进一步完善。我们在不影响 Taro 核心的情况下尽量解决这些痛点;例如,利用 expo 重构组件库模块 @tarojs/components-rn,重写了 tab-bar 功能等。并开发独立壳应用,本地不用配置原生开发环境也可以进行 React-Native 开发。

对于 Taro 社区的开发者而言,应用可以 ”无缝“ 扩展到 React-Native 平台;另一方面,React-Native 社区的开发者可以把 Taro 项目当作是 React-Native 应用的另一种项目模板,开发体验”无缝“衔接。

新增组件&API

最后但也是非常重要的一点,就是提升 Taro 组件和 API 规范在 React-Native 端的覆盖度。要真正做到一套代码,多端运行,核心在于组件 & API 规范的覆盖度。我们支持基础型组件(例如容器类、表单类等)的同时,也逐渐在进一步完善其它类型的组件以及 API。

  • tabbar & Navigator

tab 结构是最常用的页面布局之一,仅仅通过 app 配置,就能生成一个多 tab 的 React-Native 页面。

  • 媒体组件

对于富有表现力的应用,总需要视频、音频以及相机组件的加持;我们已经把这些都集成进来了。

  • 扫描二维码

当下扫码经济如火如荼,基于开发者调研结果我们新增了 API scanCode,希望解决实际项目开发中的痛点。

  • 长列表

React-Native 已经有非常成熟的方案来优化长列表,在此基础上我们实现了组件 VirtualList。当开发者碰到长列表卡顿时,不妨尝试这个新组件。

  • 还有更多

PickerView 、MovableView等。

设计思路

现在分三种主要场景去阐述我们是怎么实现“无缝“集成 React-Native 平台的。

  • 启动 Dev Server

运行命令 yarn dev:rn 启动 Metro bundle 服务器时,

  1. @tarojs/cli 通过编译平台扩展 presets/platforms/rn.ts,启动@tarojs/rn-runner

  2. @tarojs/rn-runner,它把 Taro 项目配置以及命令行参数转换成 MetroServer 所需的配置,并与用户自定义的 metro 配置合并(可选),然后启动 MetroServer

u6nyEv.png!mobile

  • 访问 bundle 文件

MetroServer 实质还是一个 HTTP 服务器,当发起 /index.bundle 请求时,

  1. 如果是初次请求,IncrementalBundler 会初始化 DependencyGraph,挂载 hasteFS 的 change 事件,监听文件变更;如果是非初次请求,IncrementalBundler 会生成当前请求模块相关的变更集

  2. 在模块处理过程中,@tarojs/rn-transformer 会针对入口文件和页面文件进行特殊处理,主要是支持 tab-bar、app 以及页面配置

  3. @tarojs/rn-style-transformer 会针对样式进行处理,主要完成样式语言 Sass/Less/Stylus 的覆盖

  4. 等变更集中的模块更新之后,重新让当前模块经过 Serializer 序列化成字符串返回

EraIJn6.png!mobile

  • Bundle执行

当我们启动 React-Native 原生 Android 应用时(iOS类似),

  1. CatalystInstanceImpl::runJSBundle 执行 bundle 的入口

  2. @tarojs/runtime-rn 调用 AppRegister.registerComponent 注册页面,并提供 API(@tarojs/taro-rn)和组件(@tarojs/components-rn)支持

VzyMR3j.png!mobile

如何使用

如果你已经想使用 Taro3 开发 React-Native 应用的话,步骤非常简单:

# 注意:@tarojs/cli 最新版本还未发布,体验版在标签 canary 下
$ yarn add @tarojs/cli@canary

# 创建并初始化 Taro 项目
$ npx taro init <projectName>

# 设置环境变量DEVTAG,安装体验版相关依赖:
$ export DEVTAG=@canary

# 启动 Dev Server,此处会显示监听端口号;支持 -p 选项手动指定端口
$ cd <projectName> && yarn dev:rn

下载壳应用(https://github.com/NervJS/taro-native-shell/tree/0.63.2),然后构建并安装到模拟器或真机上(以 android 为例):

# 安装依赖
$ yarn

# 构建并启动应用
$ yarn android -- --no-packager

如果缺少原生开发环境的话,直接下载应用安装包即可:android 地址(https://share.weiyun.com/xB4OJiBw)。

依次执行  开发者菜单 -> Bundle Location 修改 bundle 的地址为 http://localhost:<port> (端口号在执行 yarn dev:rn 时会在终端中输出)就可以看到入口页面了。

React-Native 相关调试以及常见使用问题请参考详细文档(https://taro-docs.jd.com/taro/docs/react-native)。

如何升级

3.x - 升级 @tarojs/cli 最新版本;把项目中 Taro 相关依赖包升级到最新版本;然后运行 yarn dev:rn, 此时会自动安装 React-Native 相关依赖。

2.x - 先删除 package.json 中 已存在的 React-Native 相关依赖项(@tarojs/rn-runner、@tarojs/runtime-rn、@taorjs/components-rn、@tarojs/router-rn 以及 @tarojs/taro-rn),然后按 3.x 的升级步骤即可。

如果升级过程中碰到问题,请通过末尾附上的渠道与我们沟通进行解决。

未来规划

  • 更高的 API、组件适配度

API、组件适配注定是一项耗时费力的长期工程,我们会继续努力提升针对 React-Native 平台的适配度。另外,也会关注组件性能问题,让应用的操作体验更加流畅。

  • 动画

动画是 React-Native 持续优化的重要场景,我们会充分释放其在这方面的优势,提升 Taro 应用的交互体验。

  • 完善开发流程

目前我们主要解决了 Taro 扩展到 React-Native 端开发环节中的核心问题,后续会进一步支持项目的发布流程,集成热更新、CI/CD 等功能。

如何贡献&问题反馈

开发过程中我们采用了静态类型约束(TypeScript)、单元测试(jest)以及静态分析(ESLint)等措施尽量控制代码质量,但是仍难免会有疏漏,非常期待大家的反馈并欢迎大家一起共建。另外,Taro 也提供了微信群方便大家与维护者们更及时沟通交流:

jaURFzR.png!mobile

团队简介

我们是 Taro3 适配 React-Native 平台的开发团队,来自房产事业群的多个 BU。主要成员:陈志庆(项目发起人+架构)、叶春喜(开发姐姐)、邢智健(android)、王信健、郝捷、祝求智、张页飞、钱杰(ios)、解成博、杨杨(测试妹子)、杜光中、罗正龙、陈昊。

Nb2iMvQ.jpg!mobile


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK