跳到主要内容

React Native 2019年6月开源更新

· 阅读需 9 分钟
Christoph Nakazawa
Christoph Nakazawa
Former Engineer @ Facebook

代码与社区健康状况

在过去六个月中,超过550名贡献者向 React Native 提交了总计2800次提交。社区中有400名贡献者创建了超过 1,150个拉取请求(Pull Requests),其中有 820个拉取请求被合并。

在过去六个月中,平均每天的拉取请求数量已从3个增加到约6个,尽管我们通过 Lean Core 计划将网站、CLI 和许多模块从 React Native 中拆分出去。现在平均未处理拉取请求数量低于25个,我们通常在数小时或几天内回复并提出建议和审查意见。

有意义的社区贡献

我们想特别强调一些我们认为非常棒的近期贡献:

Lean Core 计划

Lean Core 的主要动机是将模块从 React Native 中拆分至独立仓库,以便获得更好的维护。在短短六个月内,WebViewNetInfoAsyncStorage网站CLI 这几个仓库合计收到了超过800个拉取请求。除了更好的维护外,这些项目还能比 React Native 主体更频繁地独立发布。

我们也趁机从 React Native 中移除了过时的 polyfill 和遗留组件。过去,为支持老版本 JavaScriptCore (JSC) 中的语言特性如 MapSet,必须使用 polyfill。现在 React Native 捆绑的是更新版本,因此这些 polyfill 被删除。

这项工作仍在进行中,原生与 JavaScript 两边还有许多内容需要拆分或删除,但已有迹象表明我们成功扭转了代码体积持续增长的趋势:比如查看 JavaScript bundle 大小,一年前的 0.54 版本为530KB,6个月后 0.57 版本增长到了607KB(+77KB),而现在在 master 分支上我们看到了减小了28KB至579KB,整体差异超过100KB!

随着 Lean Core 努力的第一轮结束,我们将更加审慎地对待向 React Native 添加的新 API,并将持续评估缩小和加速 React Native 的方法,同时寻找方式赋能社区接管各个组件的维护。

用户反馈

六个月前,我们曾向社区提问 “你不喜欢 React Native 的哪些方面?”,很好地概述了人们面临的问题。我们在几个月前对该帖作了回复,现在是总结针对最重要问题取得进展的时刻:

  • 升级体验: React Native 社区围绕升级体验做了多项改进:自动链接、通过 rn-diff-purge 提供的更好升级命令及即将上线的升级助手网站。我们还会通过每个大版本发布博客,让大家了解破坏性变更和新特性。所有这些改进都会让0.60之后的升级大为简化。
  • 支持与不确定性: 众多用户对拉取请求缺乏活动及 Facebook 在 React Native 上投入的不确定感到挫败。正如前文所示,我们可以自信地说,我们已准备好迎接更多拉取请求,期待您的提议和贡献!
  • 性能: React Native 0.59 推出了全新更快的 JavaScriptCore (JSC) 版本。另外,我们一直致力于让默认启用 inline-requires 更加容易,接下来几个月还将带来更多激动人心的更新。
  • 文档: 我们近期启动了 全面重写 React Native 文档的工作。如果你想贡献文档,非常欢迎!
  • Xcode 警告: 我们已经 清理掉所有现存警告,并努力避免引入新的警告。
  • 热重载: React 团队正在开发 全新热重载系统,即将集成进 React Native。

遗憾的是,我们尚未能解决所有问题:

  • 调试: 我们修复了许多日常遇到的不便问题,但调试体验仍未达到理想水平。我们意识到调试 React Native 体验较差,未来会优先改进。
  • Metro 符号链接支持: 目前尚未找到简单直接的解决方案。不过,React Native 用户分享了各种可行的解决方案,或许能帮到你。

鉴于过去半年变化巨大,我们再次向你提问。如果您正在使用最新版本 React Native 并愿意反馈意见,请在我们新一期的 “你不喜欢 React Native 的哪些方面?” 话题下留言。

持续集成

Facebook 首先将所有拉取请求及内部更改合并至其私有仓库,然后将所有提交同步回 GitHub。Facebook 的基础设施与常见持续集成服务不同,且非所有开源测试都在 Facebook 内部完成。这导致同步到 GitHub 的提交经常会出现测试失败,修复耗费大量时间。

React Native 团队的 Héctor Ramos 过去两个月一直在改进 Facebook 和 GitHub 上的持续集成系统。现在大部分开源测试都在提交变更至 React Native Facebook 版本前运行,这将保持 GitHub 同步提交时的持续集成稳定。

接下来

务必关注我们关于 React Native 未来发展的演讲!未来几个月,Facebook React Native 团队成员将出席 Chain ReactReact Native EU 会议。同时,敬请期待即将发布的 0.60 版本。令人振奋

React Native 在 F8 大会和开源播客中的表现

· 阅读需 3 分钟
Christoph Nakazawa
Christoph Nakazawa
Former Engineer @ Facebook

本周,Eli WhiteF8 2019 大会上做了一个关于 React Native 在 Facebook 安卓和 iOS 应用中的应用的演讲。我们很高兴分享过去两年的工作成果以及我们接下来的计划。

请在Facebook 开发者网站观看视频:

F8 演讲关于 React Native

演讲亮点:

  • 我们在 2017 和 2018 年主要专注于 React Native 最大的产品——Facebook 的 Marketplace。我们与 Marketplace 团队合作,提升质量并增加产品的吸引力。至此,Marketplace 已成为 Facebook 应用中安卓和 iOS 平台上质量最高的产品之一。
  • Marketplace 的性能也是一大挑战,特别是在中端安卓设备上。过去一年我们将启动时间缩短了超过 50%,未来还会有更多改进!最大的性能提升正在被内置到 React Native 中,并将在今年晚些时候带给社区。
  • 我们有信心使用 React Native 构建出 Facebook 需要的高质量且高性能的应用。这份信心让我们敢于做更大胆的尝试,比如重新设计 React Native 核心
  • 微软支持并使用 React Native for Windows,让用户能够利用他们的技术专长和代码库渲染到微软的通用 Windows 平台。请关注下周的 Microsoft Build,届时可听他们分享更多

React Radio 播客谈开源

Eli 的演讲以介绍我们近期的开源工作收尾。我们在三月时进行了进展更新,最近,Nader DabitGant Laborde 邀请 Christoph 参加他们的播客 React Native Radio,聊了聊 React Native 在开源方面的情况。

播客亮点:

  • 我们谈到了 Facebook 的 React Native 团队如何看待开源,以及我们如何建设一个可持续且能应对 React Native 这样庞大项目规模的社区。
  • 作为 Lean Core 计划的一部分,我们正按计划移除多个模块。许多模块如 WebView 和 React Native CLI 自被拆分以来已收到超过 100 个 Pull Request。
  • 接下来,我们将重点改版 React Native 网站和文档,敬请期待!

你很快就能在喜欢的播客应用中找到本期节目,或者你也可以直接在这里收听录音:

发布 React Native 0.59

· 阅读需 6 分钟
Ryan Turner
核心维护者 & React Native 开发者

欢迎来到 React Native 0.59 版本!这是又一个重磅发布,包含了 88 位贡献者提交的 644 个提交。贡献的形式多种多样,因此 感谢你们 维护问题、培育社区,以及教授大家 React Native。本月带来了一些备受期待的变更,希望你会喜欢。

🎣 Hooks 来了

React Hooks 是本次发布的重要内容,它们让你可以跨组件重用有状态的逻辑。关于 hooks 话题非常热,如果你还没听说过,可以看看下面这些精彩资源:

务必在你的应用中尝试使用。我们希望你能像我们一样为这种复用感到振奋。

📱 更新的 JSC 带来性能提升和 Android 64 位支持

React Native 使用 JSC(JavaScriptCore)来驱动应用。Android 上的 JSC 版本较旧,很多现代 JavaScript 特性不支持。更糟的是,它的性能远不及 iOS 上的现代 JSC。随着本次版本发布,情况有了改变。

感谢 @DanielZlotin, @dulmandakh, @gengjiawen, @kmagiera@kudo 的精彩工作,JSC 赶上了近年来的进展。这带来了 64 位支持、现代 JavaScript 支持以及显著的性能提升。同时,也感谢他们让这个过程变得可维护,这样我们未来能够轻松利用 WebKit 的改进。感谢 Software Mansion 和 Expo 让这项工作成为可能。

💨 使用内联 require 加快应用启动速度

我们想帮助大家让 React Native 应用默认性能更好,并正努力将 Facebook 的优化带给社区。应用按需加载资源,避免启动时变慢。该功能称为“内联 require”,它让 Metro 可以识别可延迟加载的组件。组件层级复杂且多样的应用将会体验到最大的改进。

0.59 模板中的 metro.config.js 文件示例,展示了如何启用 inlineRequires

我们需要社区反馈效果如何,再决定是否默认启用。当你升级到 0.59 后,会看到一个新的 metro.config.js 文件;将选项切换为 true 并给我们反馈吧!更多关于内联 require,请查看性能文档并对你的应用进行基准测试。

🚅 精简核心正在进行中

React Native 是一个庞大且复杂的项目,代码库也很复杂。这使得代码不易接近贡献者,测试困难,且作为开发依赖显得臃肿。精简核心 是我们为解决这些问题,将代码迁移到独立库以便更好管理的努力。过去几个版本已经开始了这一步伐,让我们认真起来

你可能会注意到,更多组件已正式弃用。这是好消息,这些功能现在都有了活跃维护的负责人。请注意警告信息并迁移到新的库中,因为这些组件未来版本会被移除。下面表格列出了组件、弃用状态及迁移去处。

未来几个月,还会有更多组件沿着这条路走向更精简的核心。我们正在寻求帮助——欢迎前往精简核心专题参与。

👩🏽‍💻 CLI 改进

React Native 的命令行工具是开发者进入生态的入口,但长期存在问题且无官方支持。CLI 工具已迁移到新仓库,一支专注的维护团队已做出令人兴奋的改进。

日志格式更好,命令几乎瞬间执行——你会立即感受到差异:

0.58 版本中 CLI 启动较慢 0.59 版本中 CLI 几乎瞬间响应

🚀 升级到 0.59

我们听到了大家对 React Native 升级流程的反馈,正在采取措施在未来版本中提升体验。升级到 0.59 推荐使用 rn-diff-purge 来确定你当前版本与 0.59 之间的差异,然后手动应用这些更改。升级完成后,便可使用改进后的 react-native upgrade 命令(基于 rn-diff-purge)来升级到 0.60 及后续版本。

🔨 重大变更

0.59 对 Android 支持进行了整理,遵循 Google 最新推荐,可能导致已有应用出现问题。问题表现为运行时崩溃,并提示“你需要为该 Activity 使用 Theme.AppCompat 主题(或其派生)”。建议更新项目的 AndroidManifest.xml 文件,确保 android:theme 值为 AppCompat 主题(如 @style/Theme.AppCompat.Light.NoActionBar)。

react-native-git-upgrade 命令在 0.59 中被移除,建议使用新改进的 react-native upgrade 命令替代。

🤗 致谢

许多新贡献者帮助启用从 flow 类型生成原生代码解决 Xcode 警告——这是学习 React Native 工作原理和为社区做贡献的好方式。谢谢大家!期待未来出现类似的议题。

以上是我们重点标注的内容,还有很多令人激动的更新。查看完整更新请阅读更新日志。0.59 是一个巨大版本——迫不及待想让你试用。

今年剩余时间还有更多改进,敬请期待!

Ryan 和整个 React Native 核心团队

React Native 开源更新 — 2019年3月

· 阅读需 6 分钟
Christoph Nakazawa
Christoph Nakazawa
Former Engineer @ Facebook

我们于2018年第四季度公布了我们的 React Native 开源路线图,决定加大对 React Native 开源社区的投入。

在第一个里程碑中,我们重点关注识别和改进社区中最显眼的方面。我们的目标是减少未合并的拉取请求,缩减项目的表面面积,确定主要用户问题,并建立社区管理的指导方针。

在过去两个月里,我们取得了超过预期的进展。详情请继续阅读:

拉取请求

为了构建一个健康的社区,我们必须快速响应代码贡献。过去几年里,我们不太重视社区贡献的审查,积压了280个拉取请求(2018年12月)。在第一个里程碑里,我们将未处理的拉取请求数量减少到约65个。同时,每天新开的拉取请求平均数量从3.5个增长到了7个,这意味着我们在过去三个月处理了大约 600个拉取请求

我们合并了 近三分之二 的拉取请求,关闭了三分之一。关闭的拉取请求没有被合并,原因是它们已经过时或者质量较低,或者不必要地增加了项目表面面积。大部分合并的拉取请求修复了错误,提升了跨平台一致性,或者引入了新功能。其中值得一提的贡献包括提升类型安全和支持 AndroidX 的持续工作。

在 Facebook,我们直接运行 React Native 的主分支,因此所有更改都会先经过测试,确保发布版本的质量。在所有合并的拉取请求中,只有6个引发了问题:4个只影响了内部开发,2个是在发布候选版本阶段被发现。

社区中较为显眼的贡献之一是 更新后的“RedBox”屏幕。这是社区如何改善开发者体验的一个良好范例。

精简核心(Lean Core)

当前 React Native 的表面面积非常广泛,包含许多已经不维护的抽象层,这些在 Facebook 内部使用较少。我们正在努力缩减表面面积,以使 React Native 更加精简,并让社区更好地维护那些 Facebook 内部较少使用的抽象层。

在第一个里程碑中, 我们向社区寻求 Lean Core 项目的帮助。社区反响热烈,我们几乎应接不暇。 看看不到一个月内完成的所有工作

最让我们兴奋的是,维护者们积极投入,修复了长期存在的问题,增加了测试,并支持了很多长期以来请求的功能。这些模块获得的支持超过了 React Native 以往任何时候,说明这对社区来说是一个巨大进步。示例项目包括自抽取以来收到大量拉取请求的 WebView,以及由社区成员维护的 CLI,如今已收获了急需的改进和修复,详情见 React Native CLI 新家园

主要用户问题

2018年12月,我们向社区征询了他们关于 React Native 不满意的地方。我们汇总了反馈,并对每个问题进行了 回复。幸运的是,我们社区面临的许多问题,Facebook 内部同样存在。下一里程碑中,我们计划解决一些主要问题。

其中投票最高的问题之一是升级到 React Native 新版本时的开发体验。遗憾的是,我们在 Facebook 内部并不经历这一问题,因为我们直接使用主分支。值得庆幸的是,社区成员已开始着手改进这一问题:

0.59 版本发布

没有 React Native 社区,特别是 Mike GrabowskiLorenzo Sciandra 的帮助,我们无法顺利发布版本。我们希望改进发布管理流程,并计划从现在起更加积极参与:

  • 将与社区成员协作,为每个主要版本撰写博客文章。
  • 在升级新版本时,在 CLI 中直接显示重大破坏性变更。
  • 缩短发布所需时间。我们正在探索增加自动化测试并创建更完善的手动测试计划的方案。

许多计划将体现在即将发布的 React Native 0.59 版本 中。0.59 将带来 React Hooks、针对 Android 的新 64 位 JavaScriptCore 版本以及许多性能和功能提升。目前它已经作为候选版本发布,预计两周内稳定。

后续计划

接下来的两个月里,我们将继续管理拉取请求, 保持进度,同时开始减少未处理的 GitHub 问题数。我们将通过 Lean Core 项目持续缩减 React Native 表面面积。计划解决社区排名前5的主要问题。在完善社区指南后,我们将关注网站和文档。

我们非常高兴能在3月于 Facebook 伦敦接待来自社区的十多位贡献者,共同推进多项工作。感谢你们使用 React Native,希望你们能感受到我们在2019年努力带来的改进。数月后我们将带来新更新,届时也会持续合并你们的拉取请求! ⚛️✌️

2018 年 React Native 社区现状

· 阅读需 4 分钟
Lorenzo Sciandra
核心维护者 & React Native 开发者

2018 年,React Native 社区在开发和沟通 React Native 的方式上做出了诸多改变。我们相信几年后回头看,这次转变将被视为 React Native 的一个转折点。

许多人对 React Native 架构的重写感到兴奋,这就是广为人知的 Fabric。除了其他改进之外,这将解决 React Native 架构中的根本性限制,并结合 JSI 和 TurboModules 为 React Native 的未来成功奠定基础。

2018 年最大的转变是赋能 React Native 社区。从一开始,Facebook 就鼓励来自全球的开发者参与到 React Native 的开源项目中。从那时起,出现了一批核心贡献者,负责包括发布流程在内的各项事务。

这些成员采取了几个重要步骤,使整个社区在塑造项目未来方面更具权能,并提供了以下资源:

react-native-releases 📬

这个仓库创建于一月,双重作用是让所有人可以更协作的方式跟进新版本发布,并向任何想要建议 cherry-pick 的人开放版本内容的讨论(例如0.57.8及其之前所有版本)。

它是推动摆脱月度发布周期、以及目前针对 0.57.x 版本采用“长期支持”策略的主力。

这些决定的另一半功劳归于今年创建的另一个仓库:

discussions-and-proposals 🗣

这个仓库创建于七月,拓展了 React Native 更开放对话环境的理念。此前,这个需求由主仓库中标注为 For Discussion 的 issue 负责,但我们希望将这策略扩展成类似 RFC 的模式,类似其他库(如 React)采用的做法。

这一实验很快在 React Native 生命周期中找到自己的定位。Facebook 团队现正利用社区 RFC 流程来讨论 React Native 可改进之处,并协调围绕 Lean Core 项目 的努力——以及其他有趣的讨论。

@ReactNativeComm 🐣

我们意识到,沟通这些工作的方式未能达到理想效果。为方便大家更轻松地跟进 React Native 社区的所有动态(从发布到活跃讨论),我们创建了一个可以依赖的新推特账号 @ReactNativeComm

如果你没有使用该社交网络,记得你总可以通过 GitHub 观看仓库;这几个月该功能得到改进,可以仅接收版本发布的通知,建议你也试试用它。

未来展望 🎓

过去 7-8 个月来,核心贡献者增强了 React Native Community GitHub 组织 对 React Native 开发的掌控力,并加强了与 Facebook 的协作。但这始终缺乏类似项目所具备的正式架构。

该组织可以通过对所托管的所有包和仓库施行一套标准,为更广泛的开发者社区树立榜样,提供维护者相互协助、贡献符合社区共识标准代码的统一平台。

2019 年初,我们将出台这套新指南。欢迎在 专门讨论帖 中告诉我们你的看法。

我们确信,有了这些改变,社区将变得更加协作,以至于当我们达到 1.0 版本时,我们都能通过这种共同努力,继续构建(甚至更多)精彩的应用 🤗


希望你和我们一样,对这个社区的未来充满期待。我们期待你们积极参与上述仓库中的对话,或通过你们出色的代码贡献一份力量。

编程愉快!

开源路线图

· 阅读需 5 分钟
Héctor Ramos
Facebook 工程师

今年,React Native 团队专注于对 React Native 进行大规模的重新架构。正如 Sophie 在她的React Native 现状文章中提到的那样,我们已经制定了一个计划,更好地支持 Facebook 之外不断壮大的 React Native 用户和贡献者群体。现在,是时候分享我们一直在努力的更多细节了。在此之前,我想先阐述我们对开源 React Native 的长期愿景。

我们对 React Native 的愿景是……

  • 一个健康的 GitHub 仓库。 议题和拉取请求能在合理时间内得到处理。
    • 提高测试覆盖率。
    • 从 Facebook 代码库同步的提交不应破坏开源测试。
    • 更大规模的有意义的社区贡献。
  • 稳定的 API, 使与开源依赖的接口更加简单。
    • Facebook 使用与开源相同的公共 API。
    • 遵循语义化版本控制的 React Native 发布版本。
  • 充满活力的生态系统。 由社区维护的高质量 ViewManagers、本地模块以及多平台支持。
  • 优秀的文档。 重点帮助用户创建高质量体验,以及保持最新的 API 参考文档。

我们已确定以下重点领域来帮助实现这一愿景。

✂️ 精简核心

我们的目标是缩小 React Native 的代码表面,移除非核心和未使用的组件。我们将把非核心组件转移到社区,以便其更快发展。缩小的代码表面将使管理 React Native 的贡献变得更容易。

WebView 是一个我们已转交给社区的组件例子。我们正在制定工作流程,以便内部团队在从仓库移除这些组件后依然能继续使用。我们已经确定了数十个组件,准备交由社区维护。

🎁 开源内部工具与 🛠 工具链更新

Facebook 产品团队的 React Native 开发体验与开源社区存在显著差异。开源社区流行的许多工具在 Facebook 内部并未使用,Facebook 内部可能有等效的工具。在某些情况下,Facebook 团队已经习惯了外部没有的工具。这些差异在我们开源即将推出的架构工作时可能带来挑战。

我们将努力发布一些内部工具,同时提升对开源社区流行工具的支持。以下是我们将解决项目的非详尽列表:

  • 开源 JSI,并让社区能够引入自己的 JavaScript 虚拟机,替代 React Native 初始版本中的 JavaScriptCore。关于 JSI 我们将在未来文章详细介绍,目前你可以通过Parashuram 在 React Conf 的演讲了解更多。
  • 支持 Android 上的 64 位库。
  • 支持在新架构下的调试。
  • 改进对 CocoaPods、Gradle、Maven 以及新 Xcode 构建系统的支持。

✅ 测试基础设施

Facebook 工程师发布代码时,只有在通过所有测试后,才视为安全合并。这些测试用于识别修改是否可能破坏我们自己的 React Native 接口。然而,Facebook 使用 React Native 的方式与开源有所不同,这导致我们可能无意中破坏了开源版本的 React Native。

我们将增强内部测试,确保它们运行在尽可能接近开源的环境中,防止破坏测试的代码误传到开源版本。我们还将完善基础设施,使核心仓库在 GitHub 上拥有更好的测试能力,便于未来的拉取请求自带测试。

结合缩小代码表面,这将让贡献者更加自信快速地合并拉取请求。

📜 公开 API

Facebook 将通过公开 API 来使用 React Native,与开源用户一致,以减少无意的破坏性改动。我们已经开始转换内部调用点。我们的目标是统一稳定的公共 API,逐步实现 1.0 版本的语义化版本控制。

📣 交流沟通

React Native 是GitHub 上贡献者数量最多的开源项目之一。这让我们非常高兴,也想保持这一态势。我们将继续推动吸引参与者的举措,比如提升透明度和开放讨论。文档是新来 React Native 用户首要接触的内容,但过去并未被优先关注。我们想要改变这一点,从恢复自动生成的 API 参考文档开始,创造更多聚焦于打造优质用户体验的内容,并完善我们的发布说明

时间表

我们计划在未来一年左右陆续完成这些项目。其中一些工作已在进行中,比如JSI 已经开源。另一些工作会需要更长时间完成,比如缩小代码表面。我们会尽力及时向社区通报进展。请加入我们的讨论与提案仓库,这是 React Native 社区发起的一个项目,促成了本路线图中提及的多个计划。

介绍新的 iOS WebViews

· 阅读需 2 分钟
Facebook 软件工程师

长期以来,Apple 一直鼓励使用 WKWebView 代替 UIWebViews。在即将发布的 iOS 12 中,UIWebViews 将被正式弃用。React Native 的 iOS WebView 实现严重依赖于 UIWebView 类。因此,鉴于这些发展,我们为 React Native 的 WebView 组件构建了一个新的使用 WKWebView 的原生 iOS 后端。

这些更改的收尾工作已经合并在了 这个提交 中,并将在 0.57 版本中提供。

要启用这个新实现,请使用 useWebKit 属性:

<WebView
useWebKit={true}
source={{url: 'https://www.google.com'}}
/>

改进

UIWebView 没有合理的方式来促进 WebView 中运行的 JavaScript 与 React Native 之间的通信。当从 WebView 发送消息时,我们依赖一种 hack 方式将消息传递给 React Native。简而言之,我们把消息数据编码到一个带有特殊 scheme 的 url 中,并导航 WebView 到该 url。在原生端,我们拦截并取消了这次导航,从 url 中解析数据,最终调用 React Native。此实现容易出错且不安全。我很高兴地宣布,我们利用了 WKWebView 的特性,完全替换了这种方式。

WKWebView 相比 UIWebView 的其他好处包括更快的 JavaScript 执行速度和多进程架构。详情请见此 2014 WWDC

注意事项

如果你的组件使用了以下属性,切换到 WKWebView 时可能会遇到问题。当前我们建议避免使用这些属性:

行为不一致:

automaticallyAdjustContentInsetscontentInsets提交

当你给 WKWebView 添加 contentInsets 时,它不会改变 WKWebView 的视口大小。视口大小保持跟框架一样大。而在 UIWebView 中,视口会实际改变(如果 contentInsets 为正值,视口会变小)。

backgroundColor提交

在新的 iOS WebView 实现中,如果你使用此属性,背景颜色可能会闪烁。此外,WKWebView 对透明背景的渲染与 UIWebView 不同。更多细节请参考提交描述。

不支持:

scalesPageToFit提交

WKWebView 不支持 scalesPageToFit 属性,因此我们无法在 React Native 的 WebView 组件上实现此功能。

可访问性 API 更新

· 阅读需 6 分钟
陈子琪
加州大学伯克利分校学生

动机

随着技术的进步和移动应用在日常生活中的重要性日益增加,创建可访问应用的必要性也同样变得更加重要。

React Native 限制较多的可访问性 API 一直是开发者的痛点,因此我们对可访问性 API 进行了一些更新,以便更容易创建包容性的移动应用。

现有 API 存在的问题

问题一:两个完全不同但又相似的属性——accessibilityComponentType(Android)和 accessibilityTraits(iOS)

accessibilityComponentTypeaccessibilityTraits 是两个用来告知 Android 上的 TalkBack 和 iOS 上的 VoiceOver 用户正在交互的 UI 元素类型的属性。这两个属性存在的最大问题是:

  1. 它们是两个不同的属性,使用方法不同,但目的相同。 在旧 API 中,这两个属性是分开的(分别针对不同平台),这不仅不方便,也令许多开发者困惑。iOS 上的 accessibilityTraits 允许 17 个不同的取值,而 Android 上的 accessibilityComponentType 只允许 4 个取值。更重要的是,这两个属性大部分取值之间没有重叠。甚至这两个属性的输入类型也不同。accessibilityTraits 允许传入数组或单个特征,而 accessibilityComponentType 只允许传入单个值。
  2. Android 上功能非常有限。 使用旧属性时,TalkBack 只能识别 “button”、“radiobutton_checked” 和 “radiobutton_unchecked” 这几种 UI 元素。

问题二:缺乏可访问性提示(Accessibility Hints)

可访问性提示帮助使用 TalkBack 或 VoiceOver 的用户理解在交互某个无障碍元素时会发生什么,这些信息无法仅通过无障碍标签传达。这些提示可以在设置面板中开启或关闭。而之前 React Native 的 API 完全不支持可访问性提示。

问题三:忽视了反转颜色设置

一些视力障碍用户在手机上使用反转颜色以提升屏幕对比度。苹果为 iOS 提供了一个 API,允许开发者忽略特定视图上的反转颜色设置,这样图像和视频使用反转颜色时不会失真。React Native 目前尚不支持该 API。

新 API 设计

解决方案一:合并 accessibilityComponentType(Android)和 accessibilityTraits(iOS)

为了解决 accessibilityComponentTypeaccessibilityTraits 之间的混淆,我们决定将它们合并为一个属性。这是合理的,因为两者技术上功能相同,合并后开发者无需再担心平台差异细节即可构建无障碍功能。

背景

在 iOS 中,UIAccessibilityTraits 是一个可以设置在任何 NSObject 上的属性。javascript 端传入的 17 个特征值分别映射到 Objective-C 中的 UIAccessibilityTraits 元素。每个特征用一个长整型表示,所有设置的特征会使用按位或(OR)运算合并。

而在 Android 上,AccessibilityComponentType 是 React Native 提出的概念,并不直接映射到 Android 的任何属性。Android 通过无障碍代理(accessibility delegate)处理无障碍,每个视图默认有一个无障碍代理。若需定制无障碍行为,开发者必须创建新的无障碍代理,重写特定方法,并将该视图的无障碍代理替换成新代理。当开发者设置 AccessibilityComponentType 时,原生代码会基于传入的组件创建一个新的无障碍代理,并设为该视图的代理。

所做的更改

我们希望新属性能成为两个现有属性的超集。我们决定让新属性主要参考已有的 accessibilityTraits,因为 accessibilityTraits 有更多取值。Android 方面的特征功能则通过修改无障碍代理进行 polyfill。

iOS 上的 accessibilityTraits 有 17 个取值,但我们没把所有都包含进新属性,因为部分特征的使用效果未知且很少用到。

这些特征一般有两种用途:描述 UI 元素的角色,或描述其状态。观察既有用法后,大多组合了一个角色值和“state selected”或“state disabled”,或两者皆有。于是,我们决定创建两个新属性:accessibilityRoleaccessibilityState

accessibilityRole

新属性 accessibilityRole 用于告知 TalkBack 或 VoiceOver UI 元素扮演的角色。它可取以下值之一:

  • none
  • button
  • link
  • search
  • image
  • keyboardkey
  • text
  • adjustable
  • header
  • summary
  • imagebutton

该属性只允许传入一个值,因为 UI 元素通常不会同时扮演多个角色。例外是图像和按钮,故新增合成角色 imagebutton

accessibilityStates

新属性 accessibilityStates 用于告知 TalkBack 或 VoiceOver UI 元素当前的状态。它接受包含以下一个或两个值的数组:

  • selected
  • disabled

解决方案二:添加可访问性提示(Accessibility Hints)

为此,我们新增了 accessibilityHint 属性。设置该属性后,TalkBack 或 VoiceOver 会朗读提示信息。

accessibilityHint

该属性接受一个字符串形式的可访问性提示。

iOS 上,设置该属性会将对应的原生属性 AccessibilityHint 赋值给视图。若 iPhone 里开启了可访问性提示,VoiceOver 会朗读该提示。

Android 上,设置该属性则会将提示值附加到可访问标签后面。此实现方式优点是模拟了 iOS 上提示的行为,但缺点是在 Android 设置中无法像 iOS 那样关闭提示。

我们在 Android 这样设计的原因是,提示通常对应特定操作(例如点击),我们希望平台间行为一致。

解决方案三

accessibilityIgnoresInvertColors

我们将苹果的 AccessibilityIgnoresInvertColors API 暴露给 JavaScript,现在当你不希望某个视图颜色被反转(比如图片)时,可以将这个属性设为 true,其颜色就不会被反转。

新用法

这些新属性将在 React Native 0.57 版本中可用。

升级指南

如果你目前使用 accessibilityComponentTypeaccessibilityTraits,可以按以下步骤升级到新属性。

1. 使用 jscodeshift

最简单的用例可以通过运行 jscodeshift 脚本替换。

这个 脚本 会替换以下示例:

accessibilityTraits=“trait”
accessibilityTraits={[“trait”]}

accessibilityRole=“trait”

此脚本还会删除 AccessibilityComponentType 的实例(假设你设置 AccessibilityComponentType 时也会设置 AccessibilityTraits)。

2. 手动重构

对于没有对应 AccessibilityRole 值的 AccessibilityTraits 用法,以及传入多个特征的用法,则需手动重构。

通常,

accessibilityTraits= {[“button”, “selected”]}

手动改为

accessibilityRole=“button”
accessibilityStates={[“selected”]}

这些属性已经在 Facebook 的代码库中使用。Facebook 的重构过程非常简单,jscodeshift 脚本解决了半数实例,其余的手动调整,整个过程耗时甚至不到几小时。

希望你会觉得更新后的 API 很有用!请大家继续努力让应用更具可访问性!#包容性

发布 0.56 版本

· 阅读需 6 分钟
Lorenzo Sciandra
Drivetribe 核心维护者 & React Native 开发者

备受期待的 React Native 0.56 版本现已发布 🎉。这篇博客文章重点介绍了该新版本中的一些变更。我们也想借此机会说明自三月以来一直让我们忙碌的工作内容。

重大变更的两难,或者说,“何时发布?”

贡献者指南解释了所有 React Native 变更需要经过的集成流程。该项目由许多不同的工具组成,需协调和持续支持以保持一切正常运行。加上充满活力的开源社区对项目的贡献,你就可以感受到这一切规模令人头晕目眩。

随着 React Native 的广泛采用,重大破坏性变更必须非常谨慎地进行,过程并不像我们期望的那样顺畅。我们决定跳过四月和五月的发布版本,让核心团队整合和测试一套新的破坏性变更。整个过程中我们使用了专门的社区沟通渠道,确保 2018 年 6 月的(0.56.0)发布尽量让那些耐心等待稳定版本的用户能毫无困难地采用。

0.56.0 完美吗?不会,和任何软件一样,但我们已经达到了“等待更稳定”与“测试得到成功结果,准备推动发布”之间的权衡点,我们觉得可以发布了。此外,我们也知道在最终的 0.56.0 版本中存在一些尚未解决的问题,例如这个这个这个还有这个。大多数开发者升级到 0.56.0 不会有问题。对于那些因上述问题受阻的开发者,我们希望在讨论中见到你们,也期待和你们一起解决这些问题。

你可以将 0.56.0 看作向更稳定框架迈出的坚实基石:可能需要一两周的广泛采用来消除所有边缘情况,但这将促成 2018 年 7 月(0.57.0)版本的更好表现。

最后,我们要感谢67 位贡献者在共计 818 次提交中付出的努力,他们让你的应用变得更好 👏。

那么,话不多说……

重大变更

Babel 7

你们可能知道,使我们能够使用最新最强大 JavaScript 特性的转译工具 Babel 即将发布其7 版本。由于这个新版本带来了一些重要变化,我们觉得现在是升级的好时机,这也让 Metro 能够利用其改进

如果在升级过程中遇到麻烦,请参考相关文档部分

Android 支持现代化

在 Android 方面,周边工具链发生了诸多变化。我们更新到了 Gradle 3.5Android SDK 26Fresco 1.9.0 和 OkHttp 3.10.0,甚至将NDK API 目标升级到了 API 16。这些变更应该不会带来问题,还能加快构建速度。更重要的是,这有助于开发者遵守 下个月开始生效的 Play 商店新要求

在此,我们特别感谢 Dulmandakh 提交的许多 PR ,使这一切成为可能 👏。

未来我们还将继续推进相关措施,大家可以在专门的 issue中关注 Android 支持的更新规划与讨论(以及一个针对 JSC 的子话题)。

新版 Node、Xcode、React 和 Flow

Node 8 现在是 React Native 的标准版本。虽然我们其实已经开始测试了,但随着 Node 6 进入维护模式,我们现在正式全面采用 Node 8。React 也升级到了 16.4,带来了大量修复。

我们放弃了对 iOS 8 的支持,使 iOS 9 成为可支持的最低版本。我们认为这不会成为问题,因为任何能运行 iOS 8 的设备都可以升级至 iOS 9。此举让我们得以移除为运行 iOS 8 的旧设备编写的鲜少使用的兼容代码。

持续集成工具链已升级为使用 Xcode 9.4,确保所有 iOS 测试都在 Apple 提供的最新开发工具上运行。

我们已升级到 Flow 0.75,采用了很多开发者青睐的新错误格式。同时,我们为更多组件创建了类型定义。如果你的项目尚未强制使用静态类型,请考虑使用 Flow 来在编码过程中而非运行时发现问题。

以及许多其他内容……

例如,YellowBox 已被替换,提供了更佳的调试体验。

完整发布日志请参考完整变更记录。升级时请务必关注升级指南,避免迁移到此版本时出现问题。


最后说明:从本周开始,React Native 核心团队将恢复举办月度会议。我们会确保及时向大家通报会议内容,并将你的反馈纳入后续会议讨论。

祝大家编码愉快!

Lorenzo, Ryan 及整个 React Native 核心团队

**附注:**和往常一样,请大家注意 React Native 仍处于 0.x 版本,因仍有许多变更进行中——升级时请保持警惕,可能仍会遇到崩溃或故障。提交问题和 PR 时请相互帮助,遵守行为准则,屏幕那头总有真实的人。

2018 年 React Native 状况报告

· 阅读需 5 分钟
Sophie Alpert
Facebook React 工程经理

自从我们上次发布关于 React Native 的状态更新已经有一段时间了。

在 Facebook,我们比以往任何时候都更多地使用 React Native 用于许多重要项目。我们的一个最受欢迎的产品是 Marketplace,这是我们应用中的顶级标签之一,每月有 8 亿用户使用。自 2015 年创建以来,整个 Marketplace 都是用 React Native 构建的,包含了应用中不同部分的 100 多个全屏视图。

我们还在应用的许多新部分使用 React Native。如果你观看了上个月的 F8 主旨演讲,你会认识血液捐赠(Blood Donations)、危机响应(Crisis Response)、隐私快捷方式(Privacy Shortcuts)和健康检查(Wellness Checks)——这些都是最近用 React Native 构建的功能。而且,主 Facebook 应用之外的项目也使用了 React Native。新的 Oculus Go VR 头显中包含了一个完全用 React Native 构建的伴随移动应用,更不用说 React VR 驱动着头显中的许多体验。

当然,我们也使用许多其他技术来构建我们的应用。LithoComponentKit 是我们在应用中广泛使用的两个库;它们都提供类似 React 的组件 API 用于构建原生屏幕。React Native 从未以取代所有其他技术为目标——我们专注于让 React Native 本身变得更好,但我们也很高兴看到其他团队从 React Native 借鉴了许多想法,比如将即时重新加载(instant reload)引入到非 JavaScript 代码中。

架构

当我们在 2013 年启动 React Native 项目时,我们设计了一个 JavaScript 与原生之间的单一“桥”,它是异步的、可序列化的并且是批处理的。正如 React DOM 将 React 状态更新转化为对 DOM API 的命令式、变异式调用(例如 document.createElement(attrs).appendChild()),React Native 被设计为返回一个单一的 JSON 消息,列出要执行的变更,如 [["createView", attrs], ["manageChildren", ...]]。我们设计整个系统时,确保永远不依赖于同步响应,并保证这个列表中的所有内容都能完全序列化为 JSON 并且可以还原。我们这样做是为了获得灵活性:基于此架构,我们能够构建诸如Chrome 调试器这样的工具,通过 WebSocket 连接异步运行所有 JavaScript 代码。

在过去的五年中,我们发现这些最初的原则使得某些功能的开发变得更困难。异步桥意味着你无法将 JavaScript 逻辑直接集成到许多期望同步响应的原生 API 中。批处理桥排队原生调用,导致 React Native 应用调用本地实现函数变得更难。可序列化的桥意味着不必要的复制,而不能在两者间直接共享内存。对于完全用 React Native 构建的应用,这些限制通常是可以忍受的。但对于 React Native 与现有应用代码复杂集成的应用,这些限制令人沮丧。

我们正在进行一项针对 React Native 的大规模架构重构,使框架更灵活,更好地集成于混合 JavaScript/原生应用的原生系统中。 通过这个项目,我们将应用过去五年的经验,逐步将架构升级为更现代的架构。我们正在重写 React Native 的许多内部实现,但大多数变化是在底层:现有的 React Native 应用将继续运行,几乎不需要更改。

为了让 React Native 更轻量、更适合现有原生应用,此次重构有三个主要内部改变。首先,我们修改线程模型。更新 UI 时不必总是在三个不同线程上执行工作,而是可以在任意线程同步调用 JavaScript 以处理高优先级更新,同时低优先级任务仍在主线程之外保持响应性。其次,我们将引入 异步渲染功能,支持多种渲染优先级,并简化异步数据处理。最后,我们简化桥的设计,使其更快更轻量;原生与 JavaScript 之间的直接调用更高效,也便于构建诸如跨语言调用栈跟踪的调试工具。

完成这些改动后,将实现更紧密的集成。目前,集成原生导航和手势处理,或使用 UICollectionView 和 RecyclerView 等原生组件需要复杂的 hack。更新线程模型后,构建这类功能将非常简单。

随着项目接近完成,我们将在今年晚些时候发布更多细节。

社区

除了 Facebook 内部的社区外,我们很高兴看到 Facebook 之外有一个繁荣的 React Native 用户和贡献者群体。我们希望更多支持 React Native 社区,既要更好地服务 React Native 用户,也要让项目更易于贡献。

正如架构改变将帮助 React Native 更好地与其他原生基础设施互操作,React Native 在 JavaScript 侧应该更紧凑,更好地融入 JavaScript 生态系统,其中包括使虚拟机和打包工具可替换。我们知道破坏性改动的速度可能让人难以跟上,所以希望找到减少重大版本发布次数的方法。最后,我们知道某些团队需要更全面的文档,比如启动优化方面,我们的专业知识还未完全成文。期待在未来一年看到这些改进。

如果你正在使用 React Native,你就是我们社区的一员;请继续告诉我们如何让 React Native 更好地为你服务。

React Native 是移动开发者工具箱中的一件工具,但它是我们坚信的工具——过去一年中有 500 多位贡献者提交了超过 2500 次代码,我们每天都在不断改进它。