React Native 版本升級指南

image

前言

React Native 作為一款跨端框架媒殉,有一個最讓人頭疼的問題什黑,那就是版本更新碧库。尤其是遇到大版本更新盅粪,JavaScript钓葫、iOS 和 Android 三端的配置構(gòu)建文件都有非常大的變動,有時候三者的配置文件又互相耦合在一起票顾,往往牽一發(fā)而動全身础浮。

本文假定 React Native 升級的主導(dǎo)者是前端同學,比較熟悉 javaScript 為主的一套前端構(gòu)建流程奠骄。如果有條件豆同,升級時強烈建議拉上 iOS 和 Android 開發(fā),對于一些瑣碎的升級細節(jié)含鳞,當面溝通遠比搜索引擎高效影锈。

提示:因為每次修改和新增內(nèi)容都會隱藏文章重新審核,建議閱讀博客原文獲得最佳閱讀體驗

?? 閱讀博客原文

覺得文章對你有用的話一定要記得點贊哦 ??蝉绷,謝謝你鸭廷,這對我來說真的很重要!

<br />

一熔吗、磨刀不誤砍柴工

這部分知識我認為是最重要的辆床,畢竟版本更新是永恒的,操作流程卻是不變的桅狠。

詳細介紹各端構(gòu)建工具前讼载,我們拋開各種技術(shù)細節(jié),從整個項目的生命周期出發(fā)中跌,看看大部分產(chǎn)品是怎么做技術(shù)規(guī)劃的:

  • 產(chǎn)品早期:架構(gòu)都比較簡單维雇,整個項目拿個配置文件做配置就好了,配置文件越簡單越好晒他,xml、json 就被拿出來用了
  • 產(chǎn)品發(fā)展期:需要配置的地方變多了逸贾,這時候多加幾個配置項多加幾個參數(shù)陨仅,雖然有些繁瑣,但靜態(tài)的配置文件還夠用
  • 產(chǎn)品成熟期:人員擴增代碼膨脹铝侵,靜態(tài)的配置文件完全不夠用了灼伤,為了達到動態(tài)配置的目的,往往會引入一門腳本語言或自創(chuàng)一套 DSL 來管理相關(guān)配置
  • 產(chǎn)品晚期:一把火燒了另起爐灶(記得刪掉)

理清一個技術(shù)產(chǎn)品的生命周期后咪鲜,你就會對日常開發(fā)中配置文件有了整體的認知:那些又臭又長的配置項狐赡,亂七八糟的兼容寫法,毫無美感的 DSL疟丙,最神奇的是這些七拼八湊的東西還能把項目跑起來颖侄,Build 成功的那一刻你一定會對這種人類奇跡發(fā)出由衷的敬佩之情——原來這就叫專業(yè)啊鸟雏!

收一收澎湃的情緒,牢記上面的指導(dǎo)經(jīng)驗览祖,我們下面開始討論技術(shù)細節(jié)孝鹊。

<br />

1.【W(wǎng)eb 前端】項目配置

前端工程化一直是前端里面的熱點,雖然一直很熱展蒂,但是具體實現(xiàn)還是一團糟又活。個人認為原因主要有兩點,一個是前端構(gòu)建從無到有锰悼,相對而言基礎(chǔ)薄弱柳骄;一個是社區(qū)推動,百花齊放的同時又沒有統(tǒng)一標準箕般。就拿現(xiàn)在前端的主要配置文件來說:

  • package.json 管理 npm 包
  • 用 npm script 實現(xiàn)流程管理耐薯,有時候還要把相關(guān)腳本塞到 package.json
  • 用 eslint 進行編碼規(guī)范,有時候還要寫個 .eslintrc.js
  • 用 babel 處理語法兼容隘世,有時候還要寫個 babel.config.js
  • 用 webpack 進行項目構(gòu)建和打包發(fā)布
  • ......

上面只是列出了幾個主流配置可柿,不出意外的話,現(xiàn)在你的項目里已經(jīng)有 5 個配置文件了丙者,在 JavaScript 這個前端萬能腳本語言的粘合下复斥,這些配置文件還可以互相引用互相耦合,復(fù)雜度搞成這樣械媒,開發(fā)體驗還沒有 iOS Android 的一半好目锭。

如果你認為我只是單純的批評前端那你就理解錯了,我想表達的是纷捞,這么復(fù)雜的配置都能搞定痢虹,iOS Android 的項目配置還不是手到擒來

<br />

2.【iOS】項目配置

iOS 項目主要有兩個點:project.pbxprojCocoaPods主儡。這兩塊兒的知識了解后奖唯,升級 RN 就完全不虛了。

1?? project.pbxproj 與 Xcode

project.pbxproj 就是一個 iOS 項目的配置文件糜值,從數(shù)據(jù)結(jié)構(gòu)特點上有些像 JSON丰捷,年齡可以追溯到 NeXT,可讀性基本為 0寂汇,每次 git 合并都是純黑的噩夢病往。不信你瞅瞅下圖,這是給人看的嗎骄瓣。

project.pbxproj 代碼

可讀性這么差的東西能傳下來停巷,其實全靠 XCode 這個 IDE 給它續(xù)命。我們每次在 XCode 里修改的配置,例如 Build Settings 等選項畔勤,最后都會反映到 project.pbxproj 這個配置文件上蕾各,也算是一種另類 DSL 了。

project.pbxproj 相關(guān)的知識我推薦下面幾篇文章硼被,閱讀后會讓你對 iOS 編譯打包流程有個更深的了解:

2?? CocoaPods

CocoaPods 是一個負責管理 iOS 項目中第三方開源庫的工具示损,目前主流 iOS 工程都是用 CocoaPods 管理第三方庫的。

React Native 在 0.60 里終于用上了 CocoaPods嚷硫,和 iOS 社區(qū)步調(diào)一致了起來检访。這樣做的好處就是后續(xù)維護和迭代的壓力會小很多,鬼知道我以前升級各種 iOS SDK 的日子是怎么熬過來的仔掸。

相對 project.pbxproj脆贵,CocoaPods 無疑簡單了不少,寫配置腳本的 Ruby 語言也比較清爽起暮,Podfile 的可讀性要高很多卖氨。

platform :ios, '9.0'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'

target '項目名稱' do
  pod 'React', :path => '../node_modules/react-native/'
  pod 'React-Core', :path => '../node_modules/react-native/React'

  use_native_modules!
end

CocoaPods 的學習資料可以參考下文,不夠的話自行搜索即可:

CocoaPods 使用教程

<br />

3.【Android】項目配置

Android 的項目配置主要是由 gradle 文件控制的负懦,gradle 文件又由 Groovy 這門 JVM 系的腳本語言書寫筒捺。到這里思路就很明顯了,我們只要了解一些 Groovy 的語法和 gradle 的寫法纸厉,就能讀懂和修改 Android 的配置文件了系吭。在這里我推薦一些相關(guān)教程,讀完后就會有個大致的了解:

學習了基礎(chǔ)的語法后颗品,再回到 Android 工程上來肯尺。Android 的項目配置主要由 3 個文件控制,升級時沖突較多的也是這 3 個文件:

  • settings.gradle:用來指示 Gradle 在構(gòu)建應(yīng)用時應(yīng)將哪些模塊包含在內(nèi)
  • build.gradle:定義適用于項目中所有模塊的構(gòu)建配置
  • app/build.gradle:定義 App 的構(gòu)建配置

個人認為 Android 的 Gradle 配置還是比較容易入門的躯枢,因為 gradle 文件有個好處则吟,可以隨意的添加注釋。大家可以花點兒時間把每個配置項都加上注釋锄蹂,這樣在升級改動過程中就不容易發(fā)怵氓仲。

<br />

4.RN 官方升級助手

React Native 官方在 2019 年 7 月 0.60 大版本更新時,推出了 Upgrade Helper 這個 Diff 小工具得糜。通過這個工具我們可以方便的看出版本更新時各個配置腳本的改動敬扛,非常的方便。

React Native Upgrade Helper

<br />

二掀亩、升級流程

RN 版本升級時,我的升級流程一般是這樣的:

  • 通暢的網(wǎng)絡(luò)環(huán)境欢顷,可以自由訪問 Google 那種
  • 查看官方博客槽棍,獲取版本更新的主要內(nèi)容
  • 閱讀 RN GitHub 上的 CHANGELOG,獲取版本更新的具體改動,適配 API 變更
  • 閱讀第三方依賴的 README.md 文件炼七,是否需要同步升級
  • 使用 Upgrade Helper 做版本 Diff缆巧,并閱讀 upgrading-react-native 的相關(guān)博文,修改項目配置文件與配置腳本
  • 刪除 node_modules 與緩存豌拙,重新 Build 項目陕悬,如果 Build 失敗,根據(jù)報錯信息搜索 or 詢問 Native 開發(fā)同學
  • 回歸測試

在更新過程中按傅,個人建議 git commit 操作要盡量原子化捉超,方便后續(xù)復(fù)盤和回滾,小心駛得萬年船唯绍。

在我實際升級中拼岳,因為 React Native 0.59 到 0.60 有非常大的變動,并且業(yè)務(wù)較為復(fù)雜况芒,升級 0.60 花了兩個星期的時間:iOS 一周,Android 一周;0.61 和 0.62 的升級就比較簡單了卡儒,大概一兩個小時就可以升級好寺庄。

<br />

三、React Native 0.60 升級

2019 年 7 月 3 日 Facebook 官方發(fā)布了 React Native 0.60压汪,這是一次非常大的版本更新粪牲,雖然沒有添加新的功能,但是在底層上做了很多優(yōu)化蛾魄,向主流配置靠齊:

  • 移除 WebView 等組件交給 react-native-community 社區(qū)維護
  • 利用 CocoaPods 管理 iOS 的第三方依賴虑瀑,向 iOS 主流配置靠齊
  • Android 遷移到 AndroidX,方便后續(xù)的升級與更新
  • React Native 的一些第三方包會自動鏈接滴须,不再需要手動使用 react-native link *

0.60 升級時一定要有耐心舌狗,不可能一次性成功的,建議參考 Upgrade HelperUpgrade to React Native 0.60 這篇博文扔水,我會對文中沒有說明的地方進行補充痛侍。

升級前先確保相關(guān)第三方包已經(jīng)是最新版本。

<br />

1.React Native

JavaScript 這里相對來說好升級一些魔市,畢竟是前端程序員的主場主届。根據(jù) Diff 差異升級版本號后,還需要注意以下幾點:

1?? 部分 RN 內(nèi)置組件交給社區(qū)維護

NetInfo待德、WebViewGeolocation 從 React Native 中移除君丁,交給 react-native-community 社區(qū)維護。所以我們需要修改 import 時的路徑将宪。

Slider绘闷、AsyncStorage橡庞、CameraRollClipboard 等組件也有移除計劃印蔗,這次升級也可以順便遷移一下扒最。

值得注意的是,react-native-webview 在一次更新中為了響應(yīng) App Store 政策华嘹,已經(jīng)移除了 UIWebView吧趣,只支持 WKWebView。如果你做過移動端的適配耙厚,你肯定明白 WKWebview 對 cookie 支持不太友好强挫,這里需要重點回歸測試一下;另外一點是如果 RN 和 H5 網(wǎng)頁是通過 postMessage 的方式交互颜曾,相關(guān) API 也有一些不兼容更新纠拔,這里需要重點適配一下,具體細節(jié)可以看文檔泛豪。

2?? SwipeableFlatList 移除

SwipeableFlatList 是 React Native 在 0.5X 某個版本提供的側(cè)滑刪除列表組件稠诲,雖然一直沒有官方文檔中放出來,但是社區(qū)上已經(jīng)有很多人在使用了诡曙⊥涡穑可能對這個組件的實現(xiàn)不太滿意,官方在 0.60 里刪除了這個組件价卤。為了不讓項目報錯劝萤,我們可能需要把 SwipeableFlatList 相關(guān)的源碼拿出來自己手動維護一下,有人把相關(guān)代碼提出來維護了一個 npm 包——react-native-swipeable-lists慎璧,大家可以引入暫時過度一下床嫌。

<br />

2.iOS

0.60 版本的 React Native 支持 CocoaPods,2020 年了胸私,RN 終于支持 CocoaPods 了厌处,沒有 CocoaPods 的時代,為了使用一些 iOS 第三方庫岁疼,我們必須手動把庫文件拖到主工程里阔涉,升級和維護非常不方便。因為 0.61 版本 CocoaPods 是唯一可選包管理方案捷绒,所以強烈建議直接升級使用瑰排。

1?? 遷移到 CocoaPods & Autolinking 支持

遷移 CocoaPods 前,先在 CLI 里輸入一下命令 unlink Native Modules:

react-native unlink

unlink 后就要遷移到 CocoaPods 了暖侨。遷移前確保 Ruby 和 CocoaPods 已經(jīng)安裝成功椭住,具體的安裝過程不是本文重點就不展開了,沒有安裝的同學自行 Google 搜索字逗。

我們在 ios 目錄里新建一個文件 Podfile京郑,在里面輸入以下代碼:

platform :ios, '9.0'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'

target '項目名稱' do
  pod 'React', :path => '../node_modules/react-native/'
  pod 'React-Core', :path => '../node_modules/react-native/React'
  pod 'React-DevSupport', :path => '../node_modules/react-native/React'
  pod 'React-RCTActionSheet', :path => '../node_modules/react-native/Libraries/ActionSheetIOS'
  pod 'React-RCTAnimation', :path => '../node_modules/react-native/Libraries/NativeAnimation'
  pod 'React-RCTBlob', :path => '../node_modules/react-native/Libraries/Blob'
  pod 'React-RCTImage', :path => '../node_modules/react-native/Libraries/Image'
  pod 'React-RCTLinking', :path => '../node_modules/react-native/Libraries/LinkingIOS'
  pod 'React-RCTNetwork', :path => '../node_modules/react-native/Libraries/Network'
  pod 'React-RCTSettings', :path => '../node_modules/react-native/Libraries/Settings'
  pod 'React-RCTText', :path => '../node_modules/react-native/Libraries/Text'
  pod 'React-RCTVibration', :path => '../node_modules/react-native/Libraries/Vibration'
  pod 'React-RCTWebSocket', :path => '../node_modules/react-native/Libraries/WebSocket'

  pod 'React-cxxreact', :path => '../node_modules/react-native/ReactCommon/cxxreact'
  pod 'React-jsi', :path => '../node_modules/react-native/ReactCommon/jsi'
  pod 'React-jsiexecutor', :path => '../node_modules/react-native/ReactCommon/jsiexecutor'
  pod 'React-jsinspector', :path => '../node_modules/react-native/ReactCommon/jsinspector'
  pod 'yoga', :path => '../node_modules/react-native/ReactCommon/yoga'

  pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec'
  pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec'
  pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec'

  target '項目名稱Tests' do
    inherit! :search_paths
    # Pods for testing
  end

  use_native_modules!
end

上面這段代碼显押,pod 開頭的都是從 node_modules 目錄導(dǎo)入 react-native 相關(guān)的官方代碼。下面兩行代碼是實現(xiàn) autolink 的功能:

require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'

target '項目名稱' do
  ...
  use_native_modules!
end

Podfile 配置好后傻挂,就在 ios 文件夾下運行 pod install,安裝相關(guān)依賴挖息。

安裝成功后會生成一個 xcworkspace 空間金拒,這時候你需要退出當前的 xcodeproj 項目,打開 xcworkspace套腹。

在 xcworkspace 里绪抛,首先有兩個頂層文件夾,一個是你的 xcodeproj 項目电禀,一個是 Pods 文件夾(左圖):前者包含著你的業(yè)務(wù)代碼幢码,后者管理者安裝的第三方庫文件。這時候需要手動把 你的項目/Libraries 目錄下的 *.xcodeproj 文件手動刪除(右圖紅框 ?)尖飞,因為他們已經(jīng)存在于 Pods 文件夾里了(右圖紅框 ?)症副。

iOS目錄變化

2?? 修改 Header Search Path

上一步修改了 React Native 項目的引用方式,但還有一個問題政基,那就是尋址的頭文件路徑并沒有修改過來贞铣,我們可以觀察下面兩張圖:

  • 原來的 Header Search Path 指向的是 $(SRCROOT)/../node_modules/*

  • 使用 CocoaPods 后路徑發(fā)生了變化,變成了 $(PODS_CONFIGURATION_BUILD_DIR)/*

當時這個變化卡了我一天沮明,而且這個變化是在 project.pbxproj 中的辕坝,非常難以閱讀就忽略掉了。后來通過新建一個 RN 新項目發(fā)現(xiàn)了問題荐健。解決方法是刪除原來的 Header Search Path 內(nèi)容酱畅,手動把新的路徑添加進去。

遷移前
遷移后

上面兩步做完后可以嘗試 build 一下項目江场,大概率你會發(fā)現(xiàn)還是 build 不起來纺酸。因為錯誤原因千奇百怪我也無法一一覆蓋,這里還是問 Google 比較方便扛稽。

3?? 新增 Start Packager 腳本

到這一步假設(shè)你已經(jīng) Build 起來 iOS 項目了吁峻,這時候你會發(fā)現(xiàn)一個問題,之前 iOS build 成功后在张,會自動啟動一個 node 服務(wù)器編譯 javascript 文件用含,更新后并沒有自動啟動 node 服務(wù)器,需要我們手動 npm run start 啟動 node 服務(wù)器帮匾,非常的不方便啄骇。

問題出在哪里呢?原因是在原來的構(gòu)建方式里瘟斜,Libraries 下的 React.xcodeproj 有個 Start Packager 腳本缸夹,這個腳本會在項目 build 成功后自動啟動一個 node 服務(wù)器:

原 StartPackager 位置

遷移到 Pods 后痪寻,這個腳本就沒有了,需要我們在主工程里手動添加一下虽惭。添加方式也很簡單橡类,我在下圖也標注好了,點擊項目文件夾芽唇,在 TARGETSBuild Phases 里點擊 ?顾画,再點擊 New Run Script Phase 新增一個腳本區(qū)域,然后把下面的代碼填寫進去:

新建 StartPackager
export RCT_METRO_PORT="${RCT_METRO_PORT:=8081}"
echo "export RCT_METRO_PORT=${RCT_METRO_PORT}" > "${SRCROOT}/../node_modules/react-native/scripts/.packager.env"
if [ -z "${RCT_NO_LAUNCH_PACKAGER+xxx}" ] ; then
  if nc -w 5 -z localhost ${RCT_METRO_PORT} ; then
    if ! curl -s "http://localhost:${RCT_METRO_PORT}/status" | grep -q "packager-status:running" ; then
      echo "Port ${RCT_METRO_PORT} already in use, packager is either not running or not running correctly"
      exit 2
    fi
  else
    open "$SRCROOT/../node_modules/react-native/scripts/launchPackager.command" || echo "Can't start packager automatically"
  fi
fi

這個 Start Packager 腳本的位置也有些講究匆笤,最好放在 Check Pods Manifest.lockCompile Sources 之間研侣,要不然啟動 node 服務(wù)器時會導(dǎo)致報錯。

4?? 新增 LaunchScreen.storyboard

隨著 iPhone 產(chǎn)品線的增多炮捧,iPhone手機的尺寸也多了起來庶诡,原來一個尺寸配一個 LaunchImage 的方式逐漸變的不再適用,這時候 ? 官方建議用 LaunchScreen.storyboard 來制作啟動屏咆课,并且要求 2021 年所有 APP 都得改為此方案末誓。

具體的配置網(wǎng)上有很多教程了,大家搜索參考配置就好书蚪。我個人參考了以下教程:

5?? 修改 xcodebuild 腳本

如果項目之前有配置過自動打包腳本基显,因為這次升級遷移到 workspace,所以也得對原來的打包腳本做一些修改:

xcodebuild archive -project 項目名稱.xcodeproj

??

xcodebuild archive -workspace 項目名稱.xcworkspace

關(guān)于 xcodebuild 可以參考這兩篇文章:

<br />

3.Android

0.60 的 Android 更新主要是 3 點:

  • React Native 項目升級到 AndroidX
  • React Native 第三方依賴支持 autolink
  • 支持 Hermes善炫,一個 Facebook 開源的 Javascript 引擎

升級前先需要升級 Gradle 和 Groovy 的版本撩幽。具體細節(jié)參考 Upgrade Helper

1?? 升級到 AndroidX

AndroidX 的推進主要是 Google 官方受夠了 Android 目前混亂不堪的 android.support 箩艺,用一個統(tǒng)一的 androidx 來代替窜醉。升級跟著 Android 官方文檔走就行,我主要參考了以下文檔:

遷移工作主要是修改 import 路徑,工作量可能有些大静汤,但心理負擔較小琅催,本質(zhì)上就是改了個名字,問題不大虫给。

2?? Autolinking 支持

Autolinking 功能集成前先試試運行 react-native unlink藤抡,看看能不能自動取消鏈接。如果取消失敗抹估,就要自己手動刪除舊的 link 代碼缠黍,加入新的 Autolinking 代碼。下面我以 react-native-svg 這個第三方庫為例進行說明:

1.檢查 android/settings.gradle药蜻,刪除舊的 include 配置瓷式,加入下面新的代碼:

rootProject.name = '你的項目'

- include ':react-native-svg'
- project(':react-native-svg').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-svg/android')

+ apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
include ':app'

2.檢查 android/app/build.gradle替饿,刪除舊的配置,文件的最后一行加入一行配置:

dependencies {
-   implementation project(':react-native-svg')
}

+ apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)

3.檢查 MainApplication.java贸典,刪除舊的引用:

- @Override
- protected List<ReactPackage> getPackages() {
-   return Arrays.<ReactPackage>asList(
-     new MainReactPackage(),
-     new SvgPackage()
-   );

+   @SuppressWarnings("UnnecessaryLocalVariable")
+   List<ReactPackage> packages = new PackageList(this).getPackages();
+   return packages;
- }

值得注意的是视卢,我們業(yè)務(wù)中很有可能會自己封裝一些 Native Module,經(jīng)過上面的修改后廊驼,導(dǎo)入 Native Module 的方式也要做相應(yīng)的修改腾夯,這里可以參考官方文檔 Android Register the Module

+ import com.your-app-name.CustomToastPackage; // <-- Add this line with your package name.

protected List<ReactPackage> getPackages() {
  @SuppressWarnings("UnnecessaryLocalVariable")
  List<ReactPackage> packages = new PackageList(this).getPackages();
+   packages.add(new CustomToastPackage()); // <-- Add this line with your package name.
  return packages;
}

3?? Hermes 支持

Hermes

Hermes 是一個 Facebook 開源的 Javascript 引擎,和現(xiàn)在的 JSC 相比蔬充,在包體積和啟動速度上有所優(yōu)化。社區(qū)上已經(jīng)有很多介紹 Hermes 的文章了班利,我找了幾篇比較好的饥漫,如果對 Hermes 感興趣可以移步查看。

Hermes 的相關(guān)特性不是本文重點罗标,所以就不多介紹了庸队。

Android 想要使用 Hermes 的話,必須得使用版本號大于 0.60.4 的 React Native闯割,并且要對 android/app/build.gradle 做一些修改:

project.ext.react = [
-  entryFile: "index.js"
+  entryFile: "index.js",
+  enableHermes: false,  // clean and rebuild if changing
]

- def useIntlJsc = false
+ def jscFlavor = 'org.webkit:android-jsc:+'

dependencies {
-  if (useIntlJsc) {
-    implementation 'org.webkit:android-jsc-intl:+'
-  } else {
-    implementation 'org.webkit:android-jsc:+'
-  }
  
+  if (enableHermes) {
+    def hermesPath = "../../node_modules/hermesvm/android/";
+    debugImplementation files(hermesPath + "hermes-debug.aar")
+    releaseImplementation files(hermesPath + "hermes-release.aar")
+  } else {
+    implementation jscFlavor
+  }
}

上面只列出了主要變更彻消,如果不想用 Hermes,可以完全不做更改宙拉;如果想要嘗試一下宾尚,最好還是根據(jù) Upgrade Helper 列出的詳細變更進行修改,然后閱讀 React Native 官網(wǎng)的 Using Hermes 進行配置與調(diào)試谢澈。

<br />

四煌贴、React Native 0.61 升級

React Native 0.61 最主要的更新就是 Fast Refresh 的引入了,這個功能大大提升了開發(fā)體驗锥忿。

Fast Refresh 的加入有兩個好處牛郑,第一個是把 live reloadinghot reloading 兩個功能合二為一并做了功能加強;第二個終于支持 Hooks 熱更新了敬鬓。雖然 0.59.10 已經(jīng)支持 hooks淹朋,但是當時的函數(shù)式組件不支持熱更新,開發(fā)體驗過于差勁钉答。升級到 React Native 0.61 后就可以使用了础芍。

整體來說 0.61 的更新很小,一兩個小時就可以完成升級数尿。升級前建議參考 Upgrade HelperUpgrade to React Native 0.61 這篇博文者甲,我會對文中沒有說明的地方進行補充。

1.React Native

JavaScript 這里主要是一些 API 的變動和升級砌创,跟著報錯信息修改就好虏缸,難度并不大鲫懒。

1?? React 升級到 16.9

React 升級到 16.9 后,componentWillMount 等 API 廢棄刽辙,必須遷移到 UNSAFE_componentWillMount 等帶有 UNSAFE_ 前綴的 API窥岩。

主工程里這些 API 比較容易重構(gòu)和替換,麻煩的是一些很久沒有維護的第三方 JS 包宰缤,這時候需要自己手動 Fork 一份代碼維護颂翼,或者替換同功能的正在維護的第三方包,這個屬于技術(shù)債慨灭,只能一點一點克服朦乏。

2?? 引用路徑改動

更新后有些方法和組件的引用路徑發(fā)生了變更,需要我們適配一下:

1.ErrorUtils 默認綁定到 global 上氧骤,不需要 import ErrorUtils from ErrorUtils 導(dǎo)入了

2.RCTNetworking 引用路徑發(fā)生改變呻疹,需要修改為:

const RCTNetworking = require('react-native/Libraries/Network/RCTNetworking');

3.Dimensions 導(dǎo)入方式也發(fā)生了改變,需要修改:

import Dimensions from 'Dimensions';

??

import { Dimensions } from 'react-native';

2.iOS

0.61 之后筹陵,React Native iOS 端只支持通過 Cocoapods Link 了刽锤,如果 0.60 已經(jīng)升級到 Cocoapods 了,那么這次的 iOS 升級將會非畴澹快并思,只需要改動 Podfile 中一些庫的導(dǎo)入路徑就可以了。

具體的差異可見 Upgrade Helper语稠,非常簡單宋彼,比對修改后重新 pod install 就可以了。

3.Android

0.61 的 Android 升級也比較簡單仙畦,升級了 Gradle 版本宙暇,修改了 Hermes 的引用路徑,跟著 Upgrade Helper 的 Diff 依次修改就可议泵。

<br />

五占贫、React Native 0.62 升級

React Native 0.62 也是加強了開發(fā)者體驗,RN 項目默認引入了 Flipper 這個 Facebook 制作的移動端調(diào)試工具先口,支持了 React DevTools v4型奥,錯誤提示可以選擇新的 LogBox,比原來的錯誤提示更加友好從而更容易定位問題碉京。

除了開發(fā)體驗的加強厢汹,這次更新還支持了 Dark Mode 模式,RN 之后就可以做暗黑模式的適配了谐宙。

整體來說 0.62 的更新也很小烫葬,一兩個小時就可以完成升級。升級前建議參考 Upgrade HelperUpgrade to React Native 0.62 這篇博文,我會對文中沒有說明的地方進行補充搭综。

1.React Native

1?? useNativeDriver 顯式指定

React Native 之前使用 Animated API 時垢箕,useNativeDriver 默認值為 false,也就是說默認都是 JS 線程繪制動畫兑巾。版本升級后需要顯式指定 useNativeDriver 的值条获。我認為這個更新的意義在于每次使用 Animated 時,強迫開發(fā)者思考能不能讓動畫在 Native 線程運行蒋歌,優(yōu)化動畫體驗帅掘。

2?? LogBox 開啟

LogBox 這個功能在 0.62 里是默認關(guān)閉的,0.63 版本默認開啟堂油。0.62 里開啟方式比較 Hack修档,需要按以下步驟操作:

1.項目根目錄新建一個 before.js,然后里面只寫一行代碼:

require('react-native').unstable_enableLogBox();

2.在 JS 所有文件的入口文件 index.js 的第一行里導(dǎo)入這個文件:

import './before';

上面兩步必須嚴格執(zhí)行府框,不然的話會有紅屏報錯吱窝。

2.iOS

1?? CocoaPods 更新

Cocoapods 在這個版本里也有些改動,除去 Flipper 相關(guān)的 pod寓免,改動非常小,根據(jù) Upgrade Helper 中的 Diff 差異修改就好计维。

2?? Swift 支持

0.62 升級需要修改一些 Swift 相關(guān)的配置袜香,具體升級流程可見 React Native 0.62 upgrade (Xcode)

3.Android

0.61 的 Android 升級也比較簡單,升級了 Gradle 版本鲫惶,除去 Flipper 相關(guān)的更新蜈首,改動非常小,跟著 Upgrade Helper 的 Diff 依次修改就可欠母。

4.Flipper

[圖片上傳失敗...(image-981308-1598410413140)]

0.62 之后欢策,Flipper 在 RN 的項目里是默認添加的赏淌,可以方便的查看 Layout踩寇、network 和 log 等信息。

舊項目升級時六水,Flipper 其實是可選的俺孙,安裝有些波折,上手體驗了一下感覺如下(版本為 0.52.1):

  • 把 React Native 的 console.log 信息和 Native 的 log 信息和在一個應(yīng)用里掷贾,比較方便查看
  • 可以查看 Native Layout 布局睛榄,并且內(nèi)置了 React DevTools v4,兩者比對可以方便查看布局
  • Network 可以方便查看網(wǎng)絡(luò)信息想帅,這個一直是 RN 調(diào)試的一個痛點
  • 可以快速的截屏錄屏场靴,有助于和 UED 溝通
  • 支持自定義插件

上面都是優(yōu)點,缺點還是有不少的,下面我說說我用下來感覺到的不足:

  • network 對 UTF-8 支持不太好旨剥。Flipper 對編碼沒有處理好咧欣,導(dǎo)致中文顯示亂碼,我已經(jīng)給官方提了 issues泞边,但是一直沒有理我
  • network 圖片解析也有問題该押,被解析為亂碼的文本
  • log 模塊的數(shù)據(jù)都是字符串,即使你 log 的是 object阵谚,它也只是展示 JSON.stringify 后的數(shù)據(jù)

上面就是我的使用體驗蚕礼,要不要在項目中使用,我覺得大家還是親自體驗一下比較好梢什。

如果要在項目中集成 Flipper奠蹬,根據(jù) Upgrade Helper 進行集成就好,難度不是很大嗡午。

<br />

后記

上面就是 React Native 版本升級指南的內(nèi)容了囤躁,本升級教程會持續(xù)更新,為了獲得最佳體驗可以查看閱讀博客原文荔睹。

覺得文章對你有用的話一定要記得點贊哦 ??狸演,謝謝你,這對我來說真的很重要僻他!

<br />

更多優(yōu)秀文章推薦:

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末劝篷,一起剝皮案震驚了整個濱河市哨鸭,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌娇妓,老刑警劉巖像鸡,帶你破解...
    沈念sama閱讀 222,627評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異哈恰,居然都是意外死亡坟桅,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,180評論 3 399
  • 文/潘曉璐 我一進店門蕊蝗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來仅乓,“玉大人,你說我怎么就攤上這事蓬戚】溟梗” “怎么了?”我有些...
    開封第一講書人閱讀 169,346評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長豫喧。 經(jīng)常有香客問我石洗,道長,這世上最難降的妖魔是什么紧显? 我笑而不...
    開封第一講書人閱讀 60,097評論 1 300
  • 正文 為了忘掉前任讲衫,我火速辦了婚禮,結(jié)果婚禮上孵班,老公的妹妹穿的比我還像新娘涉兽。我一直安慰自己,他們只是感情好篙程,可當我...
    茶點故事閱讀 69,100評論 6 398
  • 文/花漫 我一把揭開白布枷畏。 她就那樣靜靜地躺著,像睡著了一般虱饿。 火紅的嫁衣襯著肌膚如雪拥诡。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,696評論 1 312
  • 那天氮发,我揣著相機與錄音渴肉,去河邊找鬼。 笑死爽冕,一個胖子當著我的面吹牛仇祭,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播扇售,決...
    沈念sama閱讀 41,165評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼前塔,長吁一口氣:“原來是場噩夢啊……” “哼嚣艇!你這毒婦竟也來了承冰?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,108評論 0 277
  • 序言:老撾萬榮一對情侶失蹤食零,失蹤者是張志新(化名)和其女友劉穎困乒,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體贰谣,經(jīng)...
    沈念sama閱讀 46,646評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡娜搂,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,709評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了吱抚。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片百宇。...
    茶點故事閱讀 40,861評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖秘豹,靈堂內(nèi)的尸體忽然破棺而出携御,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 36,527評論 5 351
  • 正文 年R本政府宣布啄刹,位于F島的核電站涮坐,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏誓军。R本人自食惡果不足惜袱讹,卻給世界環(huán)境...
    茶點故事閱讀 42,196評論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望昵时。 院中可真熱鬧捷雕,春花似錦、人聲如沸债查。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,698評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽盹廷。三九已至征绸,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間俄占,已是汗流浹背管怠。 一陣腳步聲響...
    開封第一講書人閱讀 33,804評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留缸榄,地道東北人渤弛。 一個月前我還...
    沈念sama閱讀 49,287評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像甚带,于是被迫代替她去往敵國和親她肯。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,860評論 2 361