Taro 3 支持 React Native

qiaohhgz 2020-12-08 21:47:52 ⋅ 888 阅读

项目背景

随着 58 业务版图不断壮大,带来的技术挑战是怎么在业务融合的过程中避免重复建设,提升开发以及多端落地效率,集团孵化了内部项目 58-rn,目前为止已经在组件化、开发流程优化、发布平台建设以及线上监控预警等环节拥有一定积累。同时,Taro 是一款优秀的跨端开发框架,在 58 众多产品线中都有使用,例如二手房、新房等。Taro 3 发布后暂不支持 React-Native 平台,于是我们向社区提交了一份实现草案,希望把 58 在 React-Native 上的技术积累分享到社区,同时也从社区对 Taro 的共建上获益。

特性

  1. 更纯粹的 React Native 支持,社区生态对接更加简便;
  2. 更好的 source-map 支持,开发调试体验大幅提升;
  3. 更加完善的样式写法支持;
  4. 与 Taro 3 React 框架一致的运行时标准;
  5. 更丰富的 API 与组件,原生依赖支持按需引入;
  6. 高稳定高性能,源码 TypeScript 开发、单元测试覆盖全;

核心关注点

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

Webpack or Metro?

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

01.png
(出处: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 的打包优化方案对接起来更容易;

4.gif

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

021.png

“零“ 成本适配 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 端。

微信图片_20201118160426.jpg

促进社区融合

目前 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 应用的另一种项目模板,开发体验”无缝“衔接。

ezgif.comoptimize.gif

新增组件 & 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

031.png

访问 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 序列化成字符串返回

041.png

Bundle执行

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

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

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

052.png

如何使用?

如果你已经想使用 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:\ (端口号在执行 yarn dev:rn 时会在终端中输出)就可以看到入口页面了。

React-Native 相关调试以及常见使用问题请参考详细文档(https://taro-docs.jd.com/taro/docs/3.x/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 等功能。


全部评论: 0

    我有话说:

    Taro 3.0.17 发布,BAT 小程序、H5 与 RN 端统一框架

    Taro 3.0.17 发布了。Taro 是一套遵循 React 语法规范的多端统一开发框架,支持React 的方式编写一次代码,生成能运行在微信小程序/百度智能小程序/支付宝小程序、H5 与

    Taro 3.0.22 发布,BAT 小程序、H5 与 RN 端统一框架

    Taro 3.0.22 发布了。Taro 是一套遵循 React 语法规范的多端统一开发框架,支持React 的方式编写一次代码,生成能运行在微信小程序/百度智能小程序/支付宝小程序、H5 与

    「开源资讯」React 17 正式版发布,构建用户界面的 JavaScript 库

    React简介 React(有时叫React.js或ReactJS)是 Facebook 推出的一个为数据提供渲染为 HTML 视图,用来构建用户界面的开源 JavaScript 库。 React

    「尝鲜」SpringBoot 快速整合Swagger 3.0

    第一步:Maven引入Swagger3.0 starter依赖 Maven项目中引入springfox-boot-starter依赖: <dependency> <

    Taro 1.2.9 发布,BAT 小程序、H5 与 RN 端统一框架

    一套 React 语法规范的多端开发解决方案 Taro

    京东技术:使用京东Taro重构小程序

    >>>>  Taro 简介 Taro 是一个基于 React 语法规范的多端统一开发框架,大家可以通过 taro

    3分钟学会 React-Native 消息推送【附源码】

    作为一个独立的APP应用怎么能没有消息推送呢?

    React Suite 4.8.6 版本更新,React UI 库

    React Suite 是一套 React 组件库,为后台产品而生,支持 Typescript,支持 RTL,支持服务端渲染。 文档: https://rsuitejs.com

    AppCode 2020.3.1 发布,支持 Apple Silicon

    AppCode 2020.3.1 现已发布,并且用户可以在下载时选择支持 Apple Silicon 的版本。 具体更新内容 Swift:OptionSet 成员未在数组中解析 使用

    WebStorm 2020.3 发布,支持 Tailwind CSS,Git Staging 等

    WebStorm 2020.3 发布,这是本年度最后一次重大更新。重要更新包括对 Tailwind CSS 的支持,将 IDE 主题与操作系统设置同步,以及 Git Staging。 外观 重做

    Spring Framework 5.3.3 发布,初步支持 JDK 17

    Spring Framework 5.3.3 现已发布。Spring Framework 是一个分层应用程序框架,可在任何类型的部署平台上为基于 Java 的现代企业应用程序提供

    Python 3.9.1 发布,支持苹果 M1 和 macOS 11 Big Sur

    Python 3.9.1 已正式发布。Python 3.9.1 是 Python 3.9 的第一个维护版本,也是第一个在 Apple Silicon 上原生支持 macOS 11 Big Sur 的

    React UI 库:React Suite 4.0.2 版本更新-多项Bug修复和新手入门

    React Suite 是一套 React 组件库,为后台产品而生。

    BeetlSQL 3.0.10 发布,内置 sega 事务支持

    本次发布主要增加了分布式Sega事务支持,适合多数据源 按照社区建议,修改了了springboot 的 yml配置方式 修改了@Jackson和@UpdateTime,本来是用来作为例子,但社区

    BeetlSQL 3.1.0 发布,Spring Saga 事务支持

    本次发布增强了Saga在spring下的支持,使用kafka提供重试以及重试失败后放入丢弃队列里 Saga是用来在微服务中的长事务管理,具备ACID中的ACD,不具备I,隔离性。在一定业务条件下

    Taro UI 2.0 发布:新增自定义主题功能,适配更多小程序

    Taro UI 发布已有半年,在此期间,不断完善组件库的功能和特性,新增了许多组件和小工具...

    滴滴开源基于 React 的移动端开发组件库-Pile.js

    Pile.js 是滴滴开发的基于 React 的移动端开发组件库。 轻量,易用,包含 52 个交互功能,支持多语言与自定义皮肤。可以非常轻松的创建用户交互界面,让前端开发更专注于业务逻辑的实现。