React Native v0.79 更新

发布于:2025-04-15 ⋅ 阅读:(29) ⋅ 点赞:(0)

今天我们很高兴地发布 React Native 0.79!

这个版本在多个方面带来了性能提升,同时还修复了若干 bug。首先,得益于延迟哈希机制,Metro 的启动速度更快了,同时也稳定支持了 package exports。由于 JS bundle 压缩方式的优化,Android 的启动时间也得到了改善,此外还有更多改进。

亮点概览:

  • 全新的 Metro 功能
  • JSC 移至社区维护包
  • iOS:兼容 Swift 的原生模块注册机制
  • Android:更快的 App 启动速度
  • 移除远程 JS 调试功能

重点详解:

Metro:更快的启动速度与支持 package exports

本次版本集成了 Metro 0.82。该版本通过引入延迟哈希机制,将首次执行 yarn start 的速度提升了超过 3 倍(在大型项目和 monorepo 中提升更显著),从而大幅提升了日常开发体验以及 CI 构建速度。

在 Metro 0.82 中,我们将 package.json 中的 exportsimports 字段解析机制正式升级为稳定特性。exports 支持最早是在 React Native 0.72 中引入的,而 imports 则是由社区贡献添加的 —— 从 React Native 0.79 开始,这两项功能将默认启用,适用于所有项目。

这项改进增强了与现代 npm 依赖的兼容性,并为项目结构的组织方式带来了更标准、更灵活的选项。


JSC 迁移至社区维护包

作为精简 React Native API 表面的一部分,我们正在将 JavaScriptCore(JSC)引擎迁移到一个由社区维护的包:
👉 @react-native-community/javascriptcore

这个变动不会影响正在使用 Hermes 引擎的用户

从 React Native 0.79 开始,你可以根据 readme 中的安装指引,使用社区支持的 JSC 版本。在 0.79 中,React Native 核心仍然会提供内置的 JSC 版本,但我们计划在不久的将来将其移除。

将 JSC 迁移到社区维护的包,意味着我们可以更频繁地更新 JSC 版本,向开发者提供最新功能。社区维护的 JSC 将独立于 React Native 主版本,采用单独的发布节奏。

iOS:兼容 Swift 的原生模块注册方式

在这个版本中,我们对原生模块在 React Native 运行时中的注册方式进行了重构。新的注册方式采用了与组件注册类似的机制,具体流程可以参考官方文档中的描述。

从 React Native 0.79 开始,你可以通过修改 package.json 文件来注册原生模块。我们在 ios 属性中新增了一个字段:modulesProvider

这个改动让 Swift 原生模块的集成更加简单、统一,也更符合模块化和声明式开发的趋势。

"codegenConfig": {
     "ios": {
+       "modulesProvider": {
+         "JS Name for the module": "ObjC Module provider for the pure C++ TM or a class conforming to RCTTurboModule"
+     }
    }
}

Codegen 将自动从你的 package.json 文件生成所需的相关代码。

如果你使用的是纯 C++ 原生模块,你需要按照推荐的方式进行配置:

借助这一新机制,我们统一了原生模块的注册方式 —— 无论是应用开发者还是库维护者都可以使用相同的方式进行声明。只需在 package.json 中指定相关属性,其余工作将由 Codegen 自动完成。

这个做法解决了我们在 React Native 0.77 中引入的限制 —— 当 App 使用 Swift 实现 AppDelegate 时,原本无法注册纯 C++ 原生模块。而现在的做法不再依赖于手动修改 AppDelegate,并且生成的代码能够同时兼容使用 Swift 和 Objective-C 实现的 AppDelegate

你无需再关心具体注册细节,系统将为你处理 Swift/Obj-C/C++ 多语言混用的复杂性。

Android:更快的应用启动速度

我们也对 Android 启动流程进行了优化,这一改动能显著提升启动性能。

从 React Native 0.79 开始,JavaScript Bundle 在 APK 中将不再默认压缩。此前,Android 系统在启动应用前需要先解压 JS Bundle,这个过程对启动速度造成了明显影响。

现在,我们默认将 JS Bundle 以未压缩状态打包进 APK,从而加快 Android 应用的启动速度。


💡 真实案例:
Margelo 团队在 Discord 应用中测试了这一特性,得到了显著性能提升 ——
👉 Discord 的 TTI(Time-To-Interactive)缩短了 400ms
👉 仅需一行配置改动,性能提升了 12%(测试设备:Samsung A14)。


不过需要注意的是,未压缩的 Bundle 会占用更多设备存储空间。如果你对应用大小比较敏感,可以通过在 app/build.gradle 文件中配置 enableBundleCompression 属性,来重新启用压缩行为。

react {
  // ...
  // If you want to compress the JS bundle (slower startup, less
  // space consumption)
  enableBundleCompression = true
  // If don't you want to compress the JS bundle (faster startup,
  // higher space consumption)
  enableBundleCompression = false

  // Default is `false`
}

请注意,虽然本次更新会使 APK 的体积有所增加,但用户在下载安装时并不会因此额外付费或耗费更多流量 —— 因为 APK 文件在通过网络分发时是经过压缩的。


⚠️ 重大变更(Breaking Changes)

移除远程 JS 调试功能

为了持续优化调试体验,我们正式移除了通过 Chrome 进行的远程 JS 调试功能。这一传统的调试方式早在 React Native 0.73 中就已被弃用,并转为运行时手动开启选项。

现在请统一使用 React Native DevTools 进行更现代、稳定的调试。

🚫 注意:React Native 将不再兼容社区维护的 react-native-debugger 项目。

如果你希望继续使用第三方调试工具(如 Redux DevTools),我们推荐:

  • 使用 Expo DevTools Plugins
  • 或者集成这些工具的独立版本(standalone version)

👉 详细内容请参阅官方的专门博文。


内部模块迁移为标准 export 语法

为了让 JavaScript 代码库更加现代化,我们对 React Native 内部的多个模块做了更新:将原本的 module.exports 写法统一替换为标准的 export 语法。

此次更新涉及约 46 个 API,具体列表请查阅官方 changelog。

这一更改对已有代码的影响较为微妙,但需要注意的是:

如果你的项目中引用了这些内部模块,请确保使用符合 ES Module 规范的导入方式,否则可能导致引用异常。

我们预计这项改动的实际影响非常有限,尤其是对于使用 TypeScript 和 import 语法的项目。不过,建议你在升级后检查是否存在类型错误,并及时更新相关代码。


💡 小贴士:强烈建议统一使用根路径 react-native 进行导入

作为一个通用建议,我们强烈推荐始终从 'react-native' 根路径导入模块,以避免未来因内部结构调整而带来的兼容性问题。

🚧 预告:
在下一个版本中,我们将正式弃用深层导入(deep imports),作为明确 React Native 公共 JavaScript API 的一部分(详见官方 RFC)。


✅ 建议使用方式:

import { View, Text } from 'react-native'; // ✅ 推荐

🚫 避免以下写法:

import View from 'react-native/Libraries/Components/View/View'; // ❌ 将被弃用

通过统一使用根路径导入,你的代码将更稳健、可维护,也更符合官方未来的发展方向。

⚠️ 其他破坏性变更(Other Breaking Changes)

以下列出的是一些可能对你项目代码产生轻微影响的变更,虽然不大,但仍值得关注:


❌ 不再支持无单位的 box-shadow 与 filter 长度值

为了使 React Native 更加符合 CSS / Web 标准,我们不再支持 box-shadow 和 filter 中的无单位长度值

例如,以下写法将不再被渲染:

boxShadow: '1 1 black' // ❌ 错误写法

你应该改为明确指定单位,如:

boxShadow: '1px 1px black' // ✅ 正确写法

❌ 移除 normalize-color 中对错误 hwb() 语法的支持

为与 Web 标准对齐,我们对 hwb() 色彩函数的语法做了限制。

历史上 React Native 曾支持带逗号的写法,例如:

hwb(0, 0%, 100%) // ❌ 不再支持

现在应使用符合规范的空格分隔写法:

hwb(0 0% 100%) // ✅ 推荐写法

👉 可阅读官方说明了解更多(注:实际链接请查看官方发布内容)。


📦 Libraries/Core/ExceptionsManager 导出方式更新

为了现代化 React Native 的 JS API,我们更新了 ExceptionsManager 的导出方式:

  • 默认导出为 ExceptionsManager 对象
  • SyntheticError 改为具名导出

更新前:

const { ExceptionsManager, SyntheticError } = require('react-native/Libraries/Core/ExceptionsManager');

更新后(推荐):

import ExceptionsManager, { SyntheticError } from 'react-native/Libraries/Core/ExceptionsManager';

这些改动虽然较小,但在大型项目或使用较多原始样式/异常处理逻辑的项目中可能会产生影响,建议在升级后仔细检查并做相应调整。