RN 升級問題記錄(0.59.5->0.61.5)

升級思路


因為項目自定義比較多,不適合用各類升級工具,主要參考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.gradleapply 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 uses react-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)

applyNativeModulesSettingsGradleapplyNativeModulesAppBuildGradle這兩個gradle方法都是在native_modules中的腳本定義的
native_modules是一個gradle腳本,在/node_modules/@react-native-community 文件夾中,源碼鏈接

  1. 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.
  2. 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時??ㄋ?br> 同步問題解決進度:

    問題定位到是一直在循環處理accessiblelabel,注釋掉就不卡了,最后用了個hack的方式臨時解決,問題應該還是出現在使用方法上,官方Demo確實沒問題
  • iOS上執行scrollTo,其實變為執行scrollToEnd
    同步問題解決進度:


    這個問題相當詭異,和iOS同學一起定位到問題是MjRefrsh這個庫生成出來的調用數組并不是代碼上的順序,也就是和RCTScrollVIew的順序不一致,導致調用錯亂了。
    解決:最后發現是升級61.5,RCTScrollVIew增加了兩個屬性的定義,加上就解決了。這個庫沒人維護了,之后RN升級都要注意同步一下,最后是換個庫吧。

總結

  • 過程還是很痛苦,主要是一大部分錯誤提示的都是無效信息,不好定位
  • 結果還是很滿意的,60+對安卓提升很明顯,是肉眼可見的快了很多
  • 感悟就是多學點端的知識很有必要
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。