升级思路

因为项目自定义比较多,不适合用各类升级工具,主要参考upgrade helper提供的改动点。
遇到问题
缓存问题
缓存问题无疑是遇到最多的,这里也就不多说,无非就是清lock/删node_module/清pod/rebuild...
Installation problem zlib: unexpected end of file

解决:
npm cache clean --force
重装pod,发现首次安装特别慢
发现clone https://github.com/CocoaPods/Specs特别慢,看了代码就会发现这个项目文件特别多,慢是肯定的。
解决:下载到本地,在本地做替换,注意.git文件。
具体可以看https://www.jianshu.com/p/73ba4ee54b72
pod libwebp始终不成功
libwebp下载的源是https://chromium.googlesource.com/webm/libwebp/,这个地址即便你全局翻墙也下不下来
解决方案:替换成github上的镜像源。
具体可以看https://www.jianshu.com/p/9e3eec3d8fe0
安卓gradle编译问题
build failed with: Could not find method enabled() for arguments [[]] on task ':app:bundleDebugJsAndAssets' of type org.gradle.api.tasks.Exec
task.dofirst不存在
解决:把apply from: "../../node_modules/react-native/react.gradle和apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)都放在app/build.grade中,app/build.grade中引用的子模块不要加以上两行,不然就有上述错误。
react.gradle主要是编译打包相关的,任务依赖这个app/build.grade
native_modules.gradle是用于自动导包的
AutoLink
基于上个问题,看文档才发现60+引入了autolink。
对于有native代码的第三方库,npm install 或者 yarn add之后,不需要执行react-native link XXX 了。iOS使用了cocoapods 来管理依赖,我们进入项目的iOS目录,执行pod install即可;安卓之前link完,会在setting.gradle、build.gradle、MainApplication.java三个文件添加引入,现在则都不需要了。
- iOS中,
podfile中多了一下的代码
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
use_native_modules!
看了一下native_modules的源码,是一个Ruby脚本文件,就是执行pod install时,执行了这个脚本
This is a function which is used inside your Podfile.
It usesreact-native configto grab a list of dependencies, and pulls out.all of the ones
which declare themselves to be iOS dependencies (via having a Podspec) and automatically
imports those into your current target.
这个脚本利用react native config这个cli命令,来抓取项目的所有依赖,然后,把有podspec文件的依赖自动的引入到cocoapods中
- Android中,
setting.gradle文件也有了变化:
rootProject.name = 'kjkDoctor'
apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle");
applyNativeModulesSettingsGradle(settings)
include ':app'
app/build.gradle最后一行多了如下代码
apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle");
applyNativeModulesAppBuildGradle(project)
applyNativeModulesSettingsGradle和 applyNativeModulesAppBuildGradle这两个gradle方法都是在native_modules中的脚本定义的
native_modules是一个gradle脚本,在/node_modules/@react-native-community 文件夹中,源码链接
- At build time, before the build script is run:
1⃣️.A first Gradle plugin (in settings.gradle) runs applyNativeModulesSettingsGradle method. It uses the package metadata from react-native config to add Android projects.
2⃣️.A second Gradle plugin (in app/build.gradle) runs applyNativeModulesAppBuildGradle method. It creates a list of React Native packages to include in the generated /android/build/generated/rn/src/main/java/com/facebook/react/PackageList.java file.- At runtime, the list of React Native packages generated in step 1.2 is registered by getPackages method of ReactNativeHost in MainApplication.java.
build阶段,在build脚本运行之前,先运行了setting.gradle中的applyNativeModulesSettingsGradle方法,这个方法利用react-native config 命令,拿到package metadata,添加依赖到你的android项目中.
然后,再运行了build.gradle中的applyNativeModulesAppBuildGradle 方法,在/android/build/generated/rn/src/main/java/com/facebook/react/PackageList.java中,生成了一系列的package (之前是在mainApplication中通过new xxxPackage()),注意这个目录是android/build下的目录,是排除版本控制的。
运行阶段,MainApplication.java 中的ReactNativeHost方法会将上一步中生成的package注册到项目中,这样就达到了与之前手动link一样的效果了.
最后,还可以通过react-native.config.js来定制化处理。
AndroidX的支持
报support.xx不存在
解决:升级三方库,比如我升了一下几个
lottie、netinfo、viewpager、smartrefreshlayout、code-push、reanimated、react-native-fast-image
代码调整
Android
去除重复库,删掉之前的引入,避免和autolink的重复。如果你使用 AS3.5以上的版本,本地编译会自动帮你去除重复库,如果是3.5以下则会报错,所以当时遇到很奇怪的问题就是代码明明一样,为什么有的同学跑起来了,有的报错了。
frescoVersion升到2.0+,支持webp
iOS
库升级,引用变化,如react-native-fast-image升级,要按新api调整,webp重新注册
JS
引用库的变化
import deepDiffer from "react-native/lib/deepDiffer"
->
react-native/Libraries/Utilities/differ/deepDiffer
React.unstable_Profiler
->
React.Profiler
生命周期废弃
Rename componentWillUpdate to UNSAFE_componentWillUpdate to suppress this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.
Warning: componentWillUpdate has been renamed, and is not recommended for use.
Warning: componentWillReceiveProps has been renamed, and is not recommended for use.
Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.
netinfo
发现新版本从offline切到online,不会更新状态,查官方说仅是模拟器的bug,真机是好的
打包机问题
- iOS: 在打包机配
libwebp的源 - iOS: xCode版本选择
- android(debug): 重复库问题
- android(release):重复资源、
watch导致内存不足的问题
样式
Android不支持字重的设置
60以下版本是可以设置100-900,60之后只有normal(400)/bold(700),看issue说是官方的限制。
解决:需要使用自定义字体
未解决问题
- iOS时常卡死
同步问题解决进度:
问题定位到是一直在循环处理accessiblelabel,注释掉就不卡了,最后用了个hack的方式临时解决,问题应该还是出现在使用方法上,官方Demo确实没问题
- iOS上执行
scrollTo,其实变为执行scrollToEnd
同步问题解决进度:
这个问题相当诡异,和iOS同学一起定位到问题是MjRefrsh这个库生成出来的调用数组并不是代码上的顺序,也就是和RCTScrollVIew的顺序不一致,导致调用错乱了。
解决:最后发现是升级61.5,RCTScrollVIew增加了两个属性的定义,加上就解决了。这个库没人维护了,之后RN升级都要注意同步一下,最后是换个库吧。
总结
- 过程还是很痛苦,主要是一大部分错误提示的都是无效信息,不好定位
- 结果还是很满意的,60+对安卓提升很明显,是肉眼可见的快了很多
- 感悟就是多学点端的知识很有必要



