React Native 0.79发布 - 更快的工具及更多改进

React Native 0.79版本发布了。

此版本在多个方面进行了性能改进,并修复了一些漏洞。首先,得益于延迟哈希技术,Metro的启动速度变快了,并且对包导出提供了稳定支持。由于JS包压缩方式的改变等原因,Android的启动时间也将得到改善。

亮点

  • 新的Metro功能
  • JSC转移到社区维护的包
  • iOS:与Swift兼容的原生模块注册
  • Android:更快的应用启动速度
  • 移除远程JS调试功能

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

此版本搭载了Metro 0.82。该版本使用延迟哈希技术,通常能将首次运行yarn start的速度提高3倍以上(在大型项目和单体仓库中提升更明显),让你的日常开发体验和持续集成(CI)构建速度更快。 ![首次打包时间对比(3倍速度提升)](bsky-metro81-bench git:(main) x rm-rf STmPDIR/metro-fite-map-;DEBUG-Met bsky-metro82-bench git:(main) x rm-rf STMPDIR/metro-fite-map-;DEBUG-H t=bundle.js index.js t=bundle.js index.js yarn run v1.22.22)

之前 之后
首次打包时间 - -

同样在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。React Native核心提供的JSC版本在0.79中仍然可用,但我们计划在不久的将来将其移除。将JSC转移到社区维护的包中,能让我们更频繁地更新JSC版本,并为你提供最新功能。社区维护的JSC版本将与React Native遵循不同的发布计划。

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

在这个版本中,我们改进了将原生模块注册到React Native运行时的方式。新方法遵循官方文档中描述的组件注册方法。从这个版本的React Native开始,你可以通过修改package.json文件来注册模块。我们在ios属性中引入了一个新的modulesProvider字段:

json 复制代码
"codegenConfig": {
    "ios": {
        "modulesProvider": {
            "JS模块名称": "用于纯C++ 原生模块的ObjC模块提供器或符合RCTTurboModule的类"
        }
    }
}

代码生成工具会根据你的package.json文件创建所有相关代码。如果你使用纯C++原生模块,则需要遵循以下推荐配置:

配置应用中的纯C++原生模块

对于纯C++原生模块,你需要添加一个新的ObjectiveC++类,将C++原生模块与应用的其他部分连接起来: CppNativeModuleProvider.h

objective-c 复制代码
#import <Foundation/Foundation.h>
#import <ReactCommon/RCTTurboModule.h>
NS_ASSUME_NONNULL_BEGIN
@interface <YourNativeModule>Provider : NSObject <RCTModuleProvider>
@end

CppNativeModuleProvider.mm

objective-c 复制代码
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);
}
@end

通过这种新方法,我们统一了应用开发者和库维护者注册原生模块的方式。库可以在它们的package.json中指定相同的属性,代码生成工具会处理剩下的工作。这种方法解决了我们在0.77版本中引入的限制,该限制阻止了使用Swift AppDelegate注册纯C++原生模块。如你所见,这些更改都不会修改AppDelegate,生成的代码对用Swift和Objective-C实现的AppDelegate都有效。

Android:更快的应用启动速度

我们还进行了一项更改,大幅提升Android应用的启动时间。从这个版本开始,我们将不再在APK中压缩JavaScript包。以前,Android系统需要在应用启动前解压JavaScript包,这在应用启动期间导致了明显的速度减慢。从这个版本开始,我们默认会提供未压缩的JavaScript包,所以你的Android应用通常会启动得更快。

Margelo团队在Discord应用上测试了这个功能,并获得了显著的性能提升:Discord的交互时间(TTI)减少了400毫秒,在三星A14上测试,通过一行代码的更改实现了12%的速度提升。另一方面,存储未压缩的包会导致应用在用户设备上占用更多空间。如果你对此有所顾虑,可以在app/build.gradle文件中使用enableBundleCompression属性来切换此行为。

groovy 复制代码
react {
    // ...
    // 如果你想压缩JS包(启动较慢,占用空间较少)
    enableBundleCompression = true
    // 如果你不想压缩JS包(启动较快,占用空间较多)
    enableBundleCompression = false
    // 默认值为`false`
}

请注意,此版本中APK的大小会增加,但你的用户在下载APK时不会承担额外的下载大小成本,因为从网络下载的APK是经过压缩的。

重大变更

移除远程JS调试功能

作为持续改进调试体验工作的一部分,我们正在移除通过Chrome进行的远程JS调试功能。这种旧的调试方法在React Native 0.73中已被弃用,并改为运行时可选启用。请使用React Native DevTools进行现代且可靠的调试。这也意味着React Native不再与react-native-debugger社区项目兼容。对于想要使用第三方调试扩展(如Redux DevTools)的开发者,我们推荐使用Expo DevTools插件,或者集成这些工具的独立版本。

内部模块更新为export语法

作为现代化JavaScript代码库工作的一部分,我们在react-native内部更新了多个实现模块,统一使用export语法替代module.exports。我们总共更新了约46个API,可在变更日志中查看。此更改对现有导入有细微影响:

情况1:默认导出

javascript 复制代码
// 已更改 - require()语法
// 旧
const ImageBackground = require('react-native/Libraries/Image/ImageBackground');
// 新
const ImageBackground = require('react-native/Libraries/Image/ImageBackground').default;
// 未更改 - import语法
import ImageBackground from 'react-native/Libraries/Image/ImageBackground';
// 推荐 - 根导入
import {ImageBackground} from 'react-native';

情况2:次要导出

这种模式的情况很少,使用根'react-native'导入时不受影响。

javascript 复制代码
// 未更改 - require()语法
const BlobRegistry = require('react-native/Libraries/Blob/BlobRegistry');
// 未更改 - 带解构的require()语法
const {register, unregister} = require('react-native/Libraries/Blob/BlobRegistry');
// 已更改 - 作为单个对象的import语法
// 旧
import BlobRegistry from 'react-native/Libraries/Blob/BlobRegistry';
// 新
import * as BlobRegistry from 'react-native/Libraries/Blob/BlobRegistry';
// 未更改 - 带解构的import语法
import {register, unregister} from 'react-native/Libraries/Blob/BlobRegistry';
// 推荐 - 根导入
import {BlobRegistry} from 'react-native';

我们预计此更改的影响非常有限,特别是对于用TypeScript编写并使用import语法的项目。请检查是否有类型错误并更新代码。

提示:强烈推荐使用根react-native导入

一般来说,我们强烈建议从根路径'react-native'导入,以避免未来出现不必要的重大变更。在下一个版本中,我们将弃用深度导入,作为更好定义React Native公共JavaScript API的一部分(见RFC)。

其他重大变更

此列表包含一系列我们认为可能对你的产品代码有轻微影响、值得注意的其他重大变更。

  • 盒阴影和滤镜中无效的无单位长度 :为了使React Native更符合CSS/Web规范,我们现在不再支持box-shadowfilter中的无单位长度。这意味着,如果你之前使用1 1 black这样的box-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作为次要导出。

升级到0.79

对于现有项目,请使用React Native升级助手查看不同React Native版本之间的代码更改,同时参考升级文档。

要创建新项目:

bash 复制代码
npx @react-native-community/cli@latest init MyProject --version latest

如果你使用Expo,React Native 0.79将在即将发布的Expo SDK 53中作为React Native的默认版本得到支持。

信息

0.79现在是React Native的最新稳定版本,0.76.x已不再受支持。更多信息请查看React Native的支持政策。我们计划在不久的将来发布0.76的最终停用更新。

标签

工程

亮点

  • Metro:更快的启动速度和包导出支持
  • JSC转移到社区维护的包
  • iOS:与Swift兼容的原生模块注册
  • Android:更快的应用启动速度

重大变更

  • 移除远程JS调试功能
  • 内部模块更新为export语法
  • 其他重大变更

总结

React Native 0.79版本带来多项更新,涵盖性能提升、功能改进和重大变更。

  1. 亮点功能
    • Metro优化 :Metro 0.82利用延迟哈希技术,使启动速度提升3倍以上,还稳定支持package.jsonexportsimports字段解析,增强与现代npm依赖的兼容性。
    • JSC迁移 :JavaScriptCore(JSC)引擎转移至社区维护的@react-native-community/javascriptcore包,社区版JSC更新更频繁,React Native核心提供的JSC版本后续将被移除,但不影响使用Hermes的用户。
    • iOS模块注册改进 :在iOS中,可通过修改package.jsonmodulesProvider字段注册原生模块,统一了开发者和库维护者的注册方式,解决了0.77版本中纯C++原生模块与Swift AppDelegate注册的限制。
    • Android启动加速 :Android默认不再压缩JavaScript包,提升了应用启动速度,如Discord应用测试时交互时间减少400毫秒,速度提升12% 。若担心空间占用,可在app/build.gradle中通过enableBundleCompression属性切换。
  2. 重大变更
    • 调试方式变更:移除通过Chrome的远程JS调试功能,推荐使用React Native DevTools,且不再兼容react-native-debugger社区项目,开发者可用Expo DevTools插件或集成独立工具进行第三方调试扩展。
    • 语法更新 :约46个内部模块从module.exports更新为export语法,对导入有细微影响,推荐从根路径'react-native'导入以避免后续问题,未来版本将弃用深度导入。
    • 其他变更 :为符合CSS/Web规范,不再支持box-shadowfilter中的无单位长度、hwb()的部分旧语法;ExceptionsManager导出更新,默认导出ExceptionsManager对象,SyntheticError作为次要导出。

小伙伴们,你们项目使用跨平台解决方案了吗?

使用的RN还是Flutter?

欢迎在评论区留言交流。

相关推荐
老猿阿浪13 小时前
突破测试环境文件上传带宽瓶颈!React Native 阿里云 OSS 直传文件格式问题攻克一
react native·阿里云
小妖怪的夏天3 天前
React Native 动态切换主题
javascript·react native·react.js
zhangguo20024 天前
react native和react在跨端架构上有什么区别?
javascript·react native·react.js
阿珊和她的猫4 天前
React Native 开发环境搭建:从零开始
javascript·react native·react.js
渔舟唱晚@4 天前
React Native 从零开始完整教程(环境配置 → 国内镜像加速 → 运行项目)
javascript·react native·react.js
小纛4 天前
React Native 太慢:kotlin-gradle-plugin-2.0.21-gradle76.jar 下载太慢
react native·kotlin·jar
爱笑的眼睛116 天前
React Native 入门 jsx tsx 基础语法
javascript·react native·react.js
西楚曹长卿6 天前
RN 获取视频封面,获取视频第一帧
android·react native·音视频·react
流星雨在线6 天前
解决 RN Switch 组件在安卓端样式很丑的问题
react native
ylineyline7 天前
React-Native Android 多行被截断
android·react native·react.js·截断·多行·cut off