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?

欢迎在评论区留言交流。

相关推荐
前端熊猫2 小时前
React Native (RN)的学习上手教程
学习·react native·react.js
wayne21417 小时前
Android与React Native混合开发打包全攻略:从零搭建自动化CI/CD流水线
react native
墨渊君5 天前
Expo 入门指南:让 React Native 开发更轻松(含环境搭建)
前端·javascript·react native
木西6 天前
React Native项目初始化及相关通用工具集成
android·react native·ios
前端极客探险家6 天前
Flutter vs React Native:跨平台移动开发框架对比
flutter·react native·react.js
木西12 天前
从0到1搭建一个RN应用从开发测试到上架全流程
android·前端·react native
哇哦谢谢你13 天前
React Native环境配置
前端·react native
getapi13 天前
Flutter和React Native在开发app中,哪个对java开发工程师更适合
java·flutter·react native