跳到主要内容

React Native 0.79 - 更快的工具以及更多

·9 分钟阅读
Alan Hughes
Alan Hughes
Expo 软件工程师
Shubham Gupta
Shubham Gupta
Dream11 软件工程师
Fabrizio Cucci
Fabrizio Cucci
Meta 软件工程师
Nicola Corti
Nicola Corti
Meta 软件工程师

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

此版本在多个方面进行了性能改进,并修复了一些错误。首先,Metro 由于延迟哈希而启动速度更快,并且稳定支持包导出。由于 JS bundle 压缩的更改以及更多改进,Android 中的启动时间也将得到改善。

亮点

亮点

Metro:更快的启动速度和包导出支持

此版本附带 Metro 0.82。此版本使用延迟哈希来提高首次 yarn start 的速度,通常提高 3 倍以上(在更大的项目和 monorepos 中更高),从而使您的开发体验和 CI 构建在日常工作中更快。

metro startup comparison

同样在 Metro 0.82 中,我们将 package.jsonexportsimports 字段解析提升为稳定版。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 与应用的其余部分粘合在一起

CppNativeModuleProvider.h
#import <Foundation/Foundation.h>
#import <ReactCommon/RCTTurboModule.h>

NS_ASSUME_NONNULL_BEGIN

@interface <YourNativeModule>Provider : NSObject <RCTModuleProvider>

@end
CppNativeModuleProvider.mm
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 属性来切换此行为。

app/build.gradle
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-shadowfilter 中的无单位长度。这意味着如果您使用的是 1 1 blackbox-shadow,我们将不会渲染。您应该改为指定单位,例如 1px 1px black
  • 从 normalize-color 中移除不正确的 hwb() 语法支持
    • 为了使 React Native 更符合 CSS/Web 规范,我们现在限制了 hwb() 的一些无效语法。从历史上看,React Native 曾经支持逗号分隔的值(例如 hwb(0, 0%, 100%)),但我们现在不再支持(您应该迁移到 hwb(0 0% 100%))。您可以在 此处 阅读有关此更改的更多信息。
  • Libraries/Core/ExceptionsManager 导出更新
    • 作为我们努力使 React Native JS API 现代化的部分工作,我们更新了 ExceptionsManager,现在导出默认的 ExceptionsManager 对象,并将 SyntheticError 作为辅助导出。

致谢

React Native 0.79 包含来自 100 位贡献者的 944 多个提交。感谢您的辛勤工作!

我们要感谢在此版本中做出重大贡献的社区成员

此外,我们还要感谢为本发布文章编写功能文档的其他作者

  • 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 的最终生命周期结束更新。