React Native 版本升级从0.72到0.75

配图为法国画家Martin Jarrie画的一只奶牛

前言

从2023年6月22日React Native官方发布0.72.0至今,一年多的时间React Native官方已经陆续发布了0.73、0.74、0.75三个版本,故决定对公司项目做版本升级,以获得更好的性能和稳定性。

我们先看下这三个版本,带来了哪些新功能、新特性:

React Native 0.73

  • 新的调试器:增加了新的调试器,弃用旧版flipper调试工具,让调试过程更加高效顺畅。

  • 稳定的符号链接支持: 简化您的开发工作流程,轻松将文件或目录链接到其他位置。

  • 支持 Android 14: 确保您的应用适配最新系统,兼容更多用户设备。

  • 全新实验性功能:无桥模式 (Bridgeless Mode),直接将 JavaScript 代码编译为原生代码,显著提升应用性能并降低内存使用量。

  • Android 平台默认使用 Kotlin。

React Native 0.74

  • Yoga 3.0:引入了 Yoga 3.0,增强了布局引擎的性能。

  • Yarn 3:初始化新React Native项目时,使用Yarn 3作为默认JavaScript包管理器,取代了之前的经典版Yarn(1.x)。

  • 新架构下的默认无桥接模式:在启用新架构时,默认采用无桥接模式(Bridgeless),以提高性能和效率。

  • 新架构批量onLayout更新:在0.74版本中,onLayout回调中的状态更新被批处理,这意味着连续的状态更新将合并成一次渲染提交,从而减少不必要的重新渲染。

  • 最低 SDK 要求提高:安卓的最低 SDK 版本要求从 Android 5.0(API 21)提高到 Android 6.0(API 23),这有助于减小应用在用户设备上占用的空间,例如新创建的应用体积减少了约13%,节约了约4MB的空间。

  • 弃用 PropTypes:完全移除了 React Native 内置的 PropTypes,推荐使用 TypeScript 进行类型检查。

  • 移除废弃API:删除了PropTypes等已弃用API,推荐开发者迁移至TypeScript

React Native 0.75

  • Yoga 3.1和布局改进:支持%值在布局中的应用,如gap、translation等属性,但仅适用于新架构。

  • 新架构稳定化:修复了一些Bug,提高了稳定性,并在React Native Directory中添加了新架构支持信息,还发布了关于支持新架构中UIManager的文章。

  • 使用框架:推荐通过框架(如Expo)构建React Native应用,将/template文件夹移至单独的仓库,并计划在2024年12月31日停止使用react-native init命令,同时改进了自动链接的性能。

  • Touchable在TypeScript中的使用限制:TouchableOpacity和TouchableHighlights组件不能再用作类型,应使用React.ElementRef或View类型。

  • 其他变更:包括Android和iOS中一些API的删除、重命名以及功能的迁移等。

由于一个完整的 React Native 项目是由 Android 项目、iOS 项目和 JavaScript 项目组成的,且都打包在一个 npm 包中,所以升级可能会有一些麻烦,大体上就是如下两种升级思路。

一,在老项目基础上升级

如果你选择通过在老项目基础上改变package.json中package版本号重新yarn的方式升级,建议你使用React Native官方推荐的升级助手:Upgrade React Native applications,通过填写app信息,会给出详细的升级方案,你只需要按照提示逐行更改就行。

Upgrade Helper

由于Upgrade Helper给出的改动方案篇幅过长,这里就不全部给出了。大致上重点在于,由于0.73默认使用kotlin、废弃了flipper且新增了新的调试器,需要将iOS podfile和安卓项目配置中关于flipper的部分全部删除,并且将.java文件删除替换为相应kotlin代码的.kt文件,还有一些安卓SDK、Gradle及npm包的升级,只需要按照提示改就行了,主要工作量都在iOS、Android原生项目配置这两块,JavaScript 项目只占很小一部分工作量。这个过程可能并不会一次成功,参考Upgrading to new versions · React Native和Upgrade Helper给出的方案,遇到什么问题解决什么问题就好了。

二,新建项目升级

以我以往的升级经验来看,在老项目的基础上通过改变package.json中package版本号重新yarn的方式升级,结合Upgrade Helper给出的改动方案,iOS、Android原生项目配置需要改动的东西很多,且很容易出现其他未知错误,通过这种方式升级,弄不好要花费掉一个星期的时间。

所以我选择直接 init 一个新的项目,然后把现有项目的 JS 代码拷贝过来,iOS、Android原生项目配置重新配置一遍的方式手动升级。这样我将在一个干净的React Native 0.75 空项目的基础上添砖加瓦,因为需要在空项目上将原来的iOS、Android原生部分重新配置一遍,看似更麻烦了,实则可以规避掉了很多在老项目基础上升级带来的未知错误,直至代码拷贝完成、升级成功。

值得一提的是,为了确保npm package的版本与React Native 0.75保持同步,我并没有直接将老项目package.json的内容直接拷贝到新项目的package.json中yarn,而是将每一个npm package都yarn add一遍,自动去安装最新的版本。

yarn完成后,安卓项目需要Android Studio重新sync Android Gradle和gradlew --refresh-dependencies刷新依赖,iOS项目需要重新pod install,这些都是必不可少的。

运行pod install后,报错:

Build target hermes-engine: Command PhaseScriptExecution failed with a nonzero exit code

此时需要将/Users/xxx/Library/Developer/Xcode/DerivedData/yourapp/Logs/Build/中的.log文件转换成可被阅读的.xcactivitylog文件才能查看到具体的报错,cd到上诉文件夹,运行如下命令:

for LOG in *.xcactivitylog; do
 NAME=`basename $LOG $EXT`
 gunzip -c -S $EXT "${NAME}${EXT}" > "${NAME}.log"
done

在xcactivitylog中得到具体的报错信息如下:

Build target hermes-engine of project Pods with configuration Release

warning: Run script build phase '[CP-User] [Hermes] Replace Hermes for the right configuration, if needed' will be run during every build because it does not specify any outputs. To address this warning, either add output dependencies to the script phase, or configure it to run in every build by unchecking "Based on dependency analysis" in the script phase. (in target 'hermes-engine' from project 'Pods')


Run script build phase '[CP-User] [Hermes] Replace Hermes for the right configuration, if needed' will be run during every build because it does not specify any outputs. To address this warning, either add output dependencies to the script phase, or configure it to run in every build by unchecking "Based on dependency analysis" in the script phase.

PhaseScriptExecution [CP-User]\ [Hermes]\ Replace\ Hermes\ for\ the\ right\ configuration,\ if\ needed /Library/Developer/Xcode/DerivedData/myProjectName-gzdlehmipieiindfjyfrhhcjupam/Build/Intermediates.noindex/ArchiveIntermediates/myProjectName/IntermediateBuildFilesPath/Pods.build/Release-iphoneos/hermes-engine.build/Script-46EB2E0002C950.sh (in target 'hermes-engine' from project 'Pods')

Node found at: /var/folders/d5/f1gffcfx27ngwvmw8v8jdm7m0000gn/T/yarn--1704767526546-0.12516067745295967/node

/Library/Developer/Xcode/DerivedData/myProjectName-gzdlehmipieiindfjyfrhhcjupam/Build/Intermediates.noindex/ArchiveIntermediates/myProjectName/IntermediateBuildFilesPath/Pods.build/Release-iphoneos/hermes-engine.build/Script-46EB2E0002C950.sh: line 9: /var/folders/d5/f1gffcfx27ngwvmw8v8jdm7m0000gn/T/yarn--1704767526546-0.12516067745295967/node: No such file or directory

Command PhaseScriptExecution failed with a nonzero exit code

通过查找方案https://github.com/facebook/react-native/issues/42221,采用软链接node到/usr/local/bin/node的方式解决了该问题,具体步骤如下:

1,找到真实的node路径

command -v node # in my machine that show => /Users/runner/hostedtoolcache/node/18.20.2/arm64/bin/node

2,链接node到 /usr/local/bin/node.

ln -s /Users/runner/hostedtoolcache/node/18.20.2/arm64/bin/node /usr/local/bin/node

或者

ln -s $(command -v node) /usr/local/bin/node 

还遇到了xcode报错:

Build service could not create build operation: unknown error while handling message: MsgHandlingError(message: "unable to initiate PIF transfer session (operation in progress?)")

通过重启xcode解决。

期间也遇到一些npm package相关的报错,由于每个项目使用的npm package都不一样,未必能为其他人带来帮助,这里就不过多论述。

至此,React Native从0.72到0.75的版本升级就完成了,总耗时一天时间。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345

推荐阅读更多精彩内容