React Native 0.79 - 更快的工具以及更多
今天我们很高兴发布 React Native 0.79!
此版本在多个方面进行了性能改进,并修复了一些错误。首先,Metro 由于延迟哈希而启动速度更快,并且稳定支持包导出。由于 JS bundle 压缩的更改以及更多改进,Android 中的启动时间也将得到改善。
亮点
亮点
Metro:更快的启动速度和包导出支持
此版本附带 Metro 0.82。此版本使用延迟哈希来提高首次 yarn start
的速度,通常提高 3 倍以上(在更大的项目和 monorepos 中更高),从而使您的开发体验和 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 版本。React Native 核心提供的 JSC 版本在 0.79 中仍然可用,但我们计划 在不久的将来 将其移除。
将 JSC 迁移到社区维护的包将使我们能够更频繁地更新 JSC 版本,并为您提供最新的功能。社区维护的 JSC 将遵循与 React Native 分开的发布计划。
iOS:Swift 兼容的 Native Modules 注册
在此版本中,我们正在改进将 Native Module 注册到 React Native 运行时的方式。新方法遵循组件的相同方法,如官方文档中所述。
从这个 React Native 版本开始,您可以通过修改 package.json
文件来注册您的模块。我们在 ios
属性中引入了一个新的 modulesProvider
字段
"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++ Native Module,则必须遵循此推荐配置
在您的应用中配置纯 C++ Native Modules
对于纯 C++ Native Modules,您需要添加一个新的 ObjectiveC++ 类,以将 C++ Native Module 与应用的其余部分粘合在一起
#import <Foundation/Foundation.h>
#import <ReactCommon/RCTTurboModule.h>
NS_ASSUME_NONNULL_BEGIN
@interface <YourNativeModule>Provider : NSObject <RCTModuleProvider>
@end
NS_ASSUME_NONNULL_END
#import "<YourNativeModule>Provider.h"
#import <ReactCommon/CallInvoker.h>
#import <ReactCommon/TurboModule.h>
#import "<YourNativeModule>.h"
@implementation NativeSampleModuleProvider
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
(const facebook::react::ObjCTurboModule::InitParams &)params
{
return std::make_shared<facebook::react::NativeSampleModule>(params.jsInvoker);
}
使用这种新方法,我们统一了应用开发者和库维护者的 Native Modules 注册。库可以在其 package.json
中指定相同的属性,Codegen 将负责其余的工作。
这种方法解决了我们在 0.77 中引入的限制,该限制阻止了使用 Swift AppDelegate
注册纯 C++ Native Module。如您所见,这些更改都不会修改 AppDelegate
,并且生成的代码将适用于使用 Swift 和 Objective-C 实现的 AppDelegate
。
Android:更快的应用启动
我们还在发布一项更改,以显着提高您的 Android 启动时间。
从这个版本开始,我们将不再压缩 APK 中的 JavaScript bundle。以前,Android 系统需要在您的应用启动之前解压缩 JavaScript bundle。这会在应用启动期间造成明显的减速。
从这个版本开始,我们将默认以未压缩的方式发布 JavaScript Bundle,因此您的 Android 应用通常会更快启动。
Margelo 团队在 Discord 应用上测试了此功能,并获得了显着的性能提升:Discord 的 time-to-interactive (TTI) 减少了 400 毫秒,这是一个 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 下载大小成本,因为 APK 在从网络下载时会进行压缩。
重大变更
移除远程 JS 调试
作为我们持续改进调试的努力的一部分,我们正在移除通过 Chrome 进行的远程 JS 调试。这种遗留的调试方法已被弃用,并在 React Native 0.73 中移至运行时选择加入。请使用 React Native DevTools 进行现代且可靠的调试。
这也意味着 React Native 不再与 react-native-debugger 社区项目兼容。对于想要使用第三方调试扩展(例如 Redux DevTools)的开发者,我们推荐 Expo DevTools Plugins,或集成这些工具的独立版本。
在 这篇专门的文章 中阅读更多内容。
内部模块更新为 export
语法
作为我们 JavaScript 代码库现代化的部分工作,我们已更新 react-native
中的许多实现模块,以一致地使用 export
语法而不是 module.exports
。
我们总共更新了大约 46 个 API,可以在 changelog 中找到。
此更改对现有导入有细微的影响
案例 1:默认导出
// CHANGED - require() syntax
- const ImageBackground = require('react-native/Libraries/Image/ImageBackground');
+ const ImageBackground = require('react-native/Libraries/Image/ImageBackground').default;
// Unchanged - import syntax
import ImageBackground from 'react-native/Libraries/Image/ImageBackground';
// RECOMMENDED - root import
import {ImageBackground} from 'react-native';
案例 2:辅助导出
这种模式的情况非常少见,再次强调,使用根 'react-native'
导入时不受影响。
// Unchanged - require() syntax
const BlobRegistry = require('react-native/Libraries/Blob/BlobRegistry');
// Unchanged - require() syntax with destructuring
const {register, unregister} = require('react-native/Libraries/Blob/BlobRegistry');
// CHANGED - import syntax as single object
- import BlobRegistry from 'react-native/Libraries/Blob/BlobRegistry';
+ import * as BlobRegistry from 'react-native/Libraries/Blob/BlobRegistry';
// Unchanged - import syntax with destructuring
import {register, unregister} from 'react-native/Libraries/Blob/BlobRegistry';
// RECOMMENDED - root import
import {BlobRegistry} from 'react-native';
我们预计此更改的影响将极其有限,特别是对于使用 TypeScript 并使用 import
语法编写的项目。请检查是否有任何类型错误以更新您的代码。
强烈推荐根 react-native
导入
作为一般建议,我们强烈建议从根 'react-native'
路径导入,以避免将来发生不必要的重大更改。在我们的下一个版本中,我们将弃用深度导入,作为更好定义 React Native 的公共 JavaScript API 的一部分(请参阅 RFC)。
其他重大变更
此列表包含一系列其他重大变更,我们怀疑这些变更可能对您的产品代码产生轻微影响,值得注意。
- box-shadow 和 filters 中无效的无单位长度:
- 为了使 React Native 更符合 CSS/Web 规范,我们现在不再支持
box-shadow
和filter
中的无单位长度。这意味着如果您使用的是1 1 black
的box-shadow
,我们将不会渲染。您应该改为指定单位,例如1px 1px black
- 为了使 React Native 更符合 CSS/Web 规范,我们现在不再支持
- 从 normalize-color 中移除不正确的 hwb() 语法支持
- 为了使 React Native 更符合 CSS/Web 规范,我们现在限制了
hwb()
的一些无效语法。从历史上看,React Native 曾经支持逗号分隔的值(例如hwb(0, 0%, 100%)
),但我们现在不再支持(您应该迁移到hwb(0 0% 100%)
)。您可以在 此处 阅读有关此更改的更多信息。
- 为了使 React Native 更符合 CSS/Web 规范,我们现在限制了
- Libraries/Core/ExceptionsManager 导出更新
- 作为我们努力使 React Native JS API 现代化的部分工作,我们更新了
ExceptionsManager
,现在导出默认的ExceptionsManager
对象,并将SyntheticError
作为辅助导出。
- 作为我们努力使 React Native JS API 现代化的部分工作,我们更新了
致谢
React Native 0.79 包含来自 100 位贡献者的 944 多个提交。感谢您的辛勤工作!
我们要感谢在此版本中做出重大贡献的社区成员
- Marc Rousavy 开发并记录了“Android:更快的应用启动”功能
- Kudo Chien 和 Oskar Kwaśniewski 致力于
@react-native-community/javascriptcore
包并撰写了“JSC 迁移到社区包”部分 - James Lawson 为 Metro 添加了对导入子路径解析的支持。
此外,我们还要感谢为本发布文章编写功能文档的其他作者
- Rob Hogan 撰写了“新的 Metro 功能”部分
- Alex Hunt 撰写了“移除远程 JS 调试”和“内部模块更新为 export 语法”部分
- Riccardo Cipolleschi 负责 iOS Native Module 注册的工作
升级到 0.79
请使用 React Native Upgrade Helper 查看现有项目在 React Native 版本之间的代码更改,以及升级文档。
要创建新项目
npx @react-native-community/cli@latest init MyProject --version latest
如果您使用 Expo,即将推出的 Expo SDK 53 将支持 React Native 0.79 作为 React Native 的默认版本。
0.79 现在是 React Native 的最新稳定版本,0.76.x 已变为不受支持。有关更多信息,请参阅 React Native 的支持策略。我们的目标是在不久的将来发布 0.76 的最终生命周期结束更新。