今天我们很高兴地发布 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
中的 exports
和 imports
字段解析机制正式升级为稳定特性。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';
这些改动虽然较小,但在大型项目或使用较多原始样式/异常处理逻辑的项目中可能会产生影响,建议在升级后仔细检查并做相应调整。