一宁舰、前言
首先我們可以在官方文檔里查到RN升級(jí)的文檔Upgrading to new React Native versions
文中介紹了兩種辦法:
1.通過(guò)react-native-git-upgrade
因?yàn)檫@個(gè)方法是一鍵式升級(jí),所以它會(huì)改變項(xiàng)目中的iOS
错维、Android
文件姑尺,由于我們的項(xiàng)目是混合型的崖飘,這樣嚴(yán)重破壞了客戶(hù)端的代碼溯街,會(huì)讓解決沖突變得十分困難色迂,不推薦香缺。
2.通過(guò)修改package.json
中react-native
的版本號(hào)來(lái)升級(jí)
這個(gè)方案只牽涉到前端,破壞性小歇僧,還可以通過(guò)rn-diff來(lái)查看到升級(jí)的一些文件改變图张,通常react-native
的升級(jí)和react
的升級(jí)是綁定的锋拖,我們就可以通過(guò)rn-diff找到相應(yīng)的版本號(hào),接下來(lái)我們就用這種辦法來(lái)進(jìn)行升級(jí)祸轮。
二兽埃、踏坑
1.修改package.json
"react": "16.4.1",
"react-native": "0.56.0",
npm i
2.運(yùn)行iOS的pod:update
發(fā)現(xiàn)pod.file
中為了兼容scrollView
的一段代碼已無(wú)用,故刪除适袜。
3.執(zhí)行react-native run-ios
錯(cuò)誤信息:
Failing run on IOS and Android because a syntax error in `local-cli`
解決:
需要升級(jí) node
,版本大于8.3
sudo npm cache clean -f && sudo npm install -g n install "n" && sudo n stable
4.啟動(dòng)后的紅屏
錯(cuò)誤信息1:
Unable to resolve module AccessibilityInfo from XXX
解決:
清除緩存
npm run reset
相當(dāng)于
watchman watch-del-all && rm -rf node_modules && npm install && npm start --reset-cache
這里還需要提到一點(diǎn)柄错,在修復(fù)過(guò)程中,經(jīng)常發(fā)現(xiàn)改動(dòng)了代碼但沒(méi)生效苦酱,這時(shí)候需要重啟服務(wù)試試
npm start --reset-cache
錯(cuò)誤信息2:
Using the export keyword between a decorator and a class is not allowed
解決:
將
@dec1
@dec2({
option1: "foo"
})
export class C {
}
改為
export
@dec1
@dec2({
option1: "foo"
})
class C {
}
錯(cuò)誤信息3:
Cannot read property 'bindings' of null at Scope.moveBindingTo
錯(cuò)誤信息4:
Property right of AssignmentExpression expected node to be of a type ["Expression"] but instead got null
解決:
3和4都是由于在0.56
版本售貌,RN
需要使用babel7+
package.json
"dependencies": {
"react": "16.4.1",
"react-native": "0.56.0",
"@babel/core": "7.0.0-beta.47",
"@babel/plugin-proposal-decorators": "7.0.0-beta.47",
"@babel/plugin-transform-classes": "7.0.0-beta.47",
"@babel/register": "7.0.0-beta.47",
}
"devDependencies": {
"babel-jest": "23.4.0",
"babel-preset-react-native": "^5",
"jest": "23.4.1",
"react-test-renderer": "16.4.1"
}
.babelrc
{
"presets": ["react-native"],
"plugins": [
["@babel/plugin-proposal-decorators", { "legacy": true }]
]
}
5.第三方庫(kù)錯(cuò)誤
react-native-scrollable-tab-view
錯(cuò)誤信息:
A trailing comma is not permitted after the rest element
解決:
由于此庫(kù)已無(wú)人維護(hù),所以把源碼放到本地維護(hù)疫萤,去除錯(cuò)誤提示代碼中的幾處逗號(hào)即可
react-native-modal
錯(cuò)誤信息:
bundling failed: Error: We don't know what to do with this node type. We were previously a Statement but we can't fit in here?
解決:
升級(jí)庫(kù)
"react-native-modal": "^6.5.0"
react-native-svg-uri
錯(cuò)誤信息:
element type is invalid expected a string (for built-in components) or a class/function check
解決:
升級(jí)庫(kù)
"react-native-svg": "^6.5.2",
"react-native-svg-uri": "^1.2.3"
react-native-root-siblings
錯(cuò)誤信息:
Exporting local "_default", which is not declared.
解決:
由于此庫(kù)近半年無(wú)人維護(hù)颂跨,所以把源碼放到本地維護(hù)
export default class {
改為
export default class xxx {
6.RN內(nèi)部組件的調(diào)整
Text/TextInput
錯(cuò)誤信息:
Text.prototype.render undefined
解決:
Text.prototype.render
改為
Text.render
create-react-class
錯(cuò)誤信息:
Module create-react-class does not exist in the Haste module map
解決:
由于把第三方庫(kù)引入本地,代碼老舊扯饶,新版已不支持create-react-class
的方式恒削,所以逐個(gè)改造為es6的語(yǔ)法
7.Android上的修改
解決完上面的問(wèn)題,在iOS
上就可以正常的跑起來(lái)了尾序,但在Android
上build
都過(guò)不了钓丰。
想到客戶(hù)端同學(xué)之前提到的一個(gè)坑:
//解決同一個(gè)庫(kù)依賴(lài)不同的版本 例如react-native 有0.49.5 有的是+ 統(tǒng)一成0.49.5
subprojects {
project.configurations.all {
resolutionStrategy.eachDependency { details ->
if (details.requested.group == 'com.facebook.react'
&& details.requested.name.contains('react-native')) {
details.useVersion "0.49.5"
}
if (details.requested.group == 'com.airbnb.android'
&& details.requested.name.contains('lottie')) {
details.useVersion "2.5.0"
}
}
}
}
他們需要把依賴(lài)的庫(kù)統(tǒng)一版本,于是把上述的0.49.5改為0.56.0
//解決同一個(gè)庫(kù)依賴(lài)不同的版本 例如react-native 有0.56.0 有的是+ 統(tǒng)一成0.56.0
subprojects {
project.configurations.all {
resolutionStrategy.eachDependency { details ->
if (details.requested.group == 'com.facebook.react'
&& details.requested.name.contains('react-native')) {
details.useVersion "0.56.0"
}
if (details.requested.group == 'com.airbnb.android'
&& details.requested.name.contains('lottie')) {
details.useVersion "2.5.0"
}
}
}
}
重新build
每币,成功了携丁,但啟動(dòng)后馬上Crash
,打開(kāi)AndroidStudio
發(fā)現(xiàn)有錯(cuò)誤信息:
解決:將這些項(xiàng)目
android
文件下的 ***.iml
文件刪掉兰怠,重新編譯錯(cuò)誤信息沒(méi)有了则北,但啟動(dòng)依舊
Crash
,這時(shí)候和客戶(hù)端同學(xué)溝通可能是so庫(kù)
的問(wèn)題痕慢,于是替換了so庫(kù)
(這里有一個(gè)小技巧尚揣,要獲得一個(gè)新版本的so庫(kù)
,可以通過(guò)創(chuàng)建一個(gè)新版本的Demo
掖举,然后從中獲瓤炱),依舊出錯(cuò),但錯(cuò)誤信息變了:
java.lang.NoClassDefFoundError: Failed resolution of: Lcom/facebook/common/soloader/SoLoaderShim;
通過(guò)Google大致猜測(cè)是gif庫(kù)
出了問(wèn)題
//fresco
compile "com.facebook.fresco:animated-gif:$rootProject.ext.frescoVersion"
compile "com.facebook.fresco:fresco:$rootProject.ext.frescoVersion"
Update Fresco to v1.9.0, okhttp3 to v3.10.0
于是把版本改為1.9.0
,重新編譯運(yùn)行塔次,一切正常方篮。
8.Android Jenkins 打包失敗
錯(cuò)誤信息:
解決:
這個(gè)問(wèn)題相當(dāng)奇葩,幾乎找不到思路励负,試過(guò)刪除目錄藕溅,再拉代碼、拉庫(kù)都無(wú)效继榆,最后是在
react-native bundle
命令加中增加一個(gè)--reset-cache
參數(shù)巾表,清除打包的緩存文件汁掠,終于可以了。
9.Android Code-Push錯(cuò)誤
錯(cuò)誤信息(issue):
facebook::react::Recoverable: Could not open file ReactNativeDevBundle.js: No such file or directory
解決:
暫時(shí)還未解決集币,code-push
的代碼中可以看到一段注釋說(shuō)明解決代碼的片段考阱,但實(shí)際仍未解決,不過(guò)好在只出現(xiàn)在本地開(kāi)發(fā)模式鞠苟,這個(gè)還需繼續(xù)跟進(jìn)乞榨。
三、總結(jié)
1.看升級(jí)日志
升級(jí)前当娱,建議看一遍官方的升級(jí)日志吃既,這樣可以對(duì)碰到的問(wèn)題有預(yù)期和解決方向。
2.勤升級(jí)
有精力的話(huà)跨细,建議更勤快的升級(jí)态秧,這樣每次升級(jí)帶來(lái)的問(wèn)題不會(huì)那么多,而且通過(guò)特定版本的升級(jí)日志通常就能定位問(wèn)題扼鞋。像這次跨多版本的升級(jí),中間涉及的錯(cuò)誤修復(fù)可能需要你仔細(xì)閱讀多個(gè)版本的升級(jí)日志愤诱,困難度增大不少云头。
3.謹(jǐn)慎選擇第三方庫(kù)
對(duì)于第三方庫(kù),除了高star淫半,還要注意它的更新頻率溃槐。
如果在更新時(shí)碰到第三方庫(kù)出錯(cuò)并很長(zhǎng)時(shí)間都無(wú)人維護(hù)了,可通過(guò)下面幾種辦法解決:
- Fork一份科吭,修改代碼昏滴,自己發(fā)npm或者引用fork地址;
- 本地新建一個(gè)組件对人,利用繼承的方式谣殊,修改源碼,引用本地的新組件牺弄;
- 把GitHub上的代碼直接放在本地維護(hù)姻几。