升級思路
因為項目自定義比較多,不適合用各類升級工具,主要參考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
文件。
具體可以看http://www.lxweimin.com/p/73ba4ee54b72
pod libwebp
始終不成功
libwebp
下載的源是https://chromium.googlesource.com/webm/libwebp/,這個地址即便你全局翻墻也下不下來
解決方案:替換成github上的鏡像源。
具體可以看http://www.lxweimin.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 config
to 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
的重復。如果你使用 AS
3.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時??ㄋ?br>
同步問題解決進度:
問題定位到是一直在循環處理accessiblelabel
,注釋掉就不卡了,最后用了個hack的方式臨時解決,問題應該還是出現在使用方法上,官方Demo確實沒問題
- iOS上執行
scrollTo
,其實變為執行scrollToEnd
同步問題解決進度:
這個問題相當詭異,和iOS同學一起定位到問題是MjRefrsh
這個庫生成出來的調用數組并不是代碼上的順序,也就是和RCTScrollVIew
的順序不一致,導致調用錯亂了。
解決:最后發現是升級61.5,RCTScrollVIew
增加了兩個屬性的定義,加上就解決了。這個庫沒人維護了,之后RN升級都要注意同步一下,最后是換個庫吧。
總結
- 過程還是很痛苦,主要是一大部分錯誤提示的都是無效信息,不好定位
- 結果還是很滿意的,60+對安卓提升很明顯,是肉眼可見的快了很多
- 感悟就是多學點端的知識很有必要