React Native 0.80 - React 19.1、JS API 变更、冻结旧架构等诸多更新
今天我们非常高兴发布 React Native 0.80!
此版本将我们在 React Native 中捆绑的 React 版本升级到最新稳定版本:19.1.0。
我们还在 JS API 中发布了一系列稳定性改进:深度导入现在会触发警告,并且我们提供了一个新的可选启用 Strict TypeScript API,它提供的类型更准确、使用更安全。
此外,React Native 的旧架构现已正式冻结,对于完全弃用旧架构后将停止工作的 API,您会开始看到警告。
亮点
亮点
JavaScript 深度导入弃用
在此版本中,我们正在努力改进和稳定 React Native 的公共 JavaScript API。迈向此目标的第一步是更好地确定我们的哪些 API 可以被应用程序和框架导入。与此一致,我们正式弃用 React Native 的深度导入(参见 RFC),并通过 ESLint 和 JS 控制台引入警告。
这些警告仅限于您项目源代码内的导入,并且可以选择退出。然而,请记住,我们的目标是在未来版本中从 React Native 的 API 中移除深度导入,这些应该更新为根导入。
// Before - import from subpath
import {Alert} from 'react-native/Libraries/Alert/Alert';
// After - import from `react-native`
import {Alert} from 'react-native';
一些 API 未在根目录导出,并且在没有深度导入的情况下将变得不可用。这是有意为之,以减少 React Native API 的总体表面积。我们有一个开放的反馈帖子用于用户问题,并且将在(至少)接下来的两个 React Native 版本中与社区合作最终确定要导出的 API。请分享您的反馈!
在我们的专文博客中了解此变更的更多信息:迈向稳定的 JavaScript API。
可选启用 Strict TypeScript API
随着上面对公共 API 中导出的重新定义,我们还在 0.80 中为 react-native
包提供了一套新的 TypeScript 类型,我们称之为 Strict TypeScript API。
选择启用 Strict TypeScript API 是我们未来稳定 React Native JavaScript API 的预览。这些新类型
- 直接从我们的源代码生成 — 提高了覆盖率和正确性,因此您可以期待更强的兼容性保证。
- 限制在 React Native 的 index 文件中 — 更严格地定义我们的公共 API,这意味着我们在进行内部文件更改时不会破坏 API。
我们与现有类型一起提供这些类型,这意味着您可以选择在准备好时迁移。此外,如果您使用的是标准 React Native API,许多应用程序应该能够无需更改即可通过验证。我们强烈鼓励早期采用者和新创建的应用程序通过您的 tsconfig.json
文件选择启用。
社区准备好后,Strict TypeScript API 将在未来成为我们的默认 API — 与深度导入的移除同步进行。
在我们的专文博客中了解此变更的更多信息:迈向稳定的 JavaScript API。
旧架构冻结及警告
React Native 的新架构自版本 0.76 起已成为默认选择,我们已经阅读了成功案例,这些项目和工具从新架构中获益匪浅。
我们最近分享了,现在认为旧架构已冻结。我们不会再在旧架构中开发新的错误修复或功能,并且在进行发布工作时将停止测试旧架构。
为了平稳过渡,如果您遇到错误或回归,我们仍然允许用户选择退出新架构。
然而,在 React Native 中同时支持两种架构是一个巨大的挑战,这影响了运行时性能、应用程序大小和我们代码库的维护。
这就是为什么我们最终需要在未来某个时间点弃用旧架构。
在 0.80 中,我们添加了一系列警告,这些警告将在 React Native DevTools 中弹出,以警告您正在使用在新架构中将不起作用的 API。
我们建议您不要忽略这些警告,并考虑将您的应用程序和库迁移到新架构,以便为未来做好准备。
您可以在我们最近在 App.js 上发表的演讲“Life After Legacy: The New Architecture Future”中了解更多关于这些更改的信息,点击此处观看。
React 19.1.0
此 React Native 版本捆绑了最新的 React 稳定版:19.1.0
您可以在发布说明中阅读关于 React 19.1.0 中引入的所有新功能和错误修复。
React 19.1.0 中一个值得注意的特性是 owner stacks 的实现和改进。这是一个仅限开发环境的功能,应有助于您识别哪个组件导致了特定的错误。
然而,我们知道如果您使用 @babel/plugin-transform-function-name
Babel 插件(在 React Native Babel Preset 中默认启用),owner stacks 在 React Native 中无法正常工作。我们将在未来的 React Native 版本中发布此问题的修复程序。
实验性特性 - React Native iOS 依赖现在已预构建
如果您正在构建 React Native iOS 应用,您可能注意到第一次原生构建会花费一些时间:在旧机器上可能需要几分钟甚至更长时间。那是因为我们需要编译整个 React Native iOS 代码及其所有依赖项。
在过去几周,我们一直在尝试预构建部分 React Native 核心代码用于 iOS,类似于 Android 上的情况,以减少首次运行 React Native 应用时的构建时间。
React Native 0.80 是第一个可以部分预构建 iOS 版 React Native 以帮助减少构建时间的版本。
在 React Native 的发布过程中,我们会生成一个名为 ReactNativeDependencies.xcframework
的 XCFramework,它是 React Native 仅依赖的第三方依赖项的预构建版本。
我们实验并基准测试了此 iOS 初始预构建节省了多少时间,在我们在 M4 机器上进行的基准测试中,使用预构建版本而不是从源代码构建,iOS 构建速度大约快 12%。
根据我们的经验,我们还观察到用户的许多错误报告是由于与 React Native 第三方依赖项相关的构建问题引起的(例如#39568)。预构建第三方依赖项使我们能够为您构建它们,这样您就不会再遇到这些构建问题了。
请注意,我们没有预构建整个 React Native:我们只预构建 Meta 不直接控制的库,例如 Folly 和 GLog。
在未来的版本中,我们还将发布其余的 React Native 核心作为预构建。
如何使用它们
此功能仍处于实验阶段,因此默认情况下未开启。
如果您想使用它们,您可以通过添加 RCT_USE_RN_DEP
环境变量来安装您的 pods
RCT_USE_RN_DEP=1 bundle exec pod install
或者,如果您想为所有开发人员启用它,您可以像这样修改您的 Podfile
if linkage != nil
Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green
use_frameworks! :linkage => linkage.to_sym
end
+ENV[‘`RCT_USE_RN_DEP`’] = ‘1’
target 'HelloWorld' do
config = use_native_modules!
请在此讨论中报告预构建可能给您和您的应用带来的任何问题。我们承诺会调查这些问题,并确保其使用对您的应用是透明的。
其他变更
Android - 借助 IPO 减小 APK 大小
此版本为所有使用 React Native 构建的 Android 应用显著减小了大小。从 0.80 开始,我们为 React Native 和 Hermes 构建启用了过程间优化 (IPO)。
这为所有 Android 应用节省了约 1Mb 的空间。
您只需将 React Native 版本更新到 0.80 即可获得此大小优势,无需对您的项目进行其他更改。
新应用屏幕重新设计
如果您没有使用 Expo,但使用的是社区 CLI 和模板,在此版本中,我们将新应用屏幕移至其自己的包中,并对其进行了全新设计。这减少了使用社区模板创建新应用时的初始代码模板,并在更大屏幕上提供了更好的体验。
关于 JSC 社区支持的通知
React Native 0.80 是 React Native 提供第一方 JSC 支持的最后一个版本。对 JSC 的支持将通过社区维护的包 @react-native-community/javascriptcore
提供。
如果您错过了此公告,可以在此处阅读更多内容
重大变更
在主包中添加了 "exports"
字段
作为 JS 稳定 API 变更的一部分,我们在 react-native
的 package.json
清单文件中引入了一个"exports"
字段。
在 0.80 中,此映射默认情况下继续暴露所有 JavaScript 子路径,因此不应造成重大破坏性变更。同时,这可能会微妙地影响 react-native
包内模块的解析方式
- 在 Metro 下,平台特定扩展将不会根据
"exports"
匹配自动展开。我们提供了许多 shim 模块来适应这种情况(#50426)。 - 在 Jest 下,模拟深度导入的能力可能会受到影响,这可能需要更新测试。
其他重大变更
此列表包含我们认为可能对您的产品代码产生轻微影响并值得注意的一系列其他重大变更
JS
- 我们将
eslint-plugin-react-hooks
版本从 v4.6.0 升级到 v5.2.0(完整变更日志在此)。react-hooks
lint 规则可能会产生新的错误信号,您需要修复或忽略它们。
Android
- 此版本将 React Native 捆绑的 Kotlin 版本升级到 2.1.20。Kotlin 2.1 引入了预览版的新语言特性,您可以在模块/组件中开始使用。您可以在官方发布说明中阅读更多信息。
- 我们删除了
StandardCharsets
类。自 0.73 版本起已弃用。您应该使用java.nio.charset.StandardCharsets
类代替。 - 我们将多个类设为内部类。这些类不属于公共 API,不应被访问。我们已经通知或向受影响的库提交了补丁
com.facebook.react.fabric.StateWrapperImpl
com.facebook.react.modules.core.ChoreographerCompat
com.facebook.react.modules.common.ModuleDataCleaner
- 我们将多个类从 Java 迁移到 Kotlin。如果您正在使用这些类,某些参数的可空性和类型已更改,因此您可能需要调整代码
com.facebook.react.devsupport
中的所有类com.facebook.react.bridge.ColorPropConverter
com.facebook.react.views.textinput.ReactEditText
com.facebook.react.views.textinput.ReactTextInputManager
iOS
- 我们删除了 RCTUtils.h 中的
RCTFloorPixelValue
字段 - React Native 中未使用RCTFloorPixelValue
方法,我们将其完全移除。
0.80 的 CHANGELOG 中列出了其他较小的重大变更。
致谢
React Native 0.80 包含了来自 127 位贡献者的 1167 次提交。感谢你们的辛勤工作!
我们要特别感谢在此版本中做出重大贡献的社区成员
- Christian Falch 在 React Native Dependencies 的 iOS 预构建方面的工作
- Iwo Plaza、Jakub Piasecki 和 Dawid Małecki 在 Strict TypeScript API 方面的工作。
此外,我们还要感谢在本发布文章中贡献文档的其他作者
- Riccardo Cipolleschi 撰写了关于 React Native Dependencies 的 iOS 预构建部分。
- Alex Hunt 负责深度导入弃用、可选启用 Strict TypeScript API、新应用屏幕重新设计。
- Nicola Corti 负责旧架构冻结及警告。
升级到 0.80
除了升级文档外,请使用React Native 升级助手查看现有项目在不同 React Native 版本之间的代码变更。
创建新项目
如果您使用 Expo,React Native 0.80 将在 Expo SDK 的 Canary 版本中支持。关于如何在 Expo 中使用 React Native 0.80 的说明也可在专用的博客文章中找到。
0.80 现在是 React Native 最新的稳定版本,0.77.x 版本将不再受支持。更多信息请参阅 React Native 的支持政策。我们计划在不久的将来发布 0.77 的最后一个生命周期结束更新。