记一次 RN 升级(0.49.5->0.56.0)

一、前言

首先我们可以在官方文档里查到RN升级的文档Upgrading to new React Native versions
文中介绍了两种办法:

1.通过react-native-git-upgrade

因为这个方法是一键式升级,所以它会改变项目中的iOSAndroid文件,由于我们的项目是混合型的,这样严重破坏了客户端的代码,会让解决冲突变得十分困难,不推荐。

2.通过修改package.jsonreact-native的版本号来升级

这个方案只牵涉到前端,破坏性小,还可以通过rn-diff来查看到升级的一些文件改变,通常react-native的升级和react的升级是绑定的,我们就可以通过rn-diff找到相应的版本号,接下来我们就用这种办法来进行升级。

二、踏坑

1.修改package.json

"react": "16.4.1",
"react-native": "0.56.0",
npm i

2.运行iOS的pod:update

发现pod.file中为了兼容scrollView的一段代码已无用,故删除。

3.执行react-native run-ios

错误信息:

Failing run on IOS and Android because a syntax error in `local-cli`

解决:
需要升级 node,版本大于8.3

sudo npm cache clean -f && sudo npm install -g n install "n" && sudo n stable

4.启动后的红屏

错误信息1:

Unable to resolve module AccessibilityInfo from XXX

解决:
清除缓存

npm run reset  
相当于 
watchman watch-del-all && rm -rf node_modules && npm install && npm start --reset-cache

这里还需要提到一点,在修复过程中,经常发现改动了代码但没生效,这时候需要重启服务试试

npm start --reset-cache

错误信息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 {
} 

错误信息3:

Cannot read property 'bindings' of null at Scope.moveBindingTo

错误信息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.第三方库错误

react-native-scrollable-tab-view

错误信息:

A trailing comma is not permitted after the rest element

解决:
由于此库已无人维护,所以把源码放到本地维护,去除错误提示代码中的几处逗号即可

react-native-modal

错误信息:

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?

解决:
升级库

"react-native-modal": "^6.5.0"

react-native-svg-uri

错误信息:

element type is invalid expected a string (for built-in components) or a class/function check 

解决:
升级库

"react-native-svg": "^6.5.2",
"react-native-svg-uri": "^1.2.3"

react-native-root-siblings

错误信息:

Exporting local "_default", which is not declared.

解决:
由于此库近半年无人维护,所以把源码放到本地维护

export default class {
改为
export default class xxx { 

6.RN内部组件的调整

Text/TextInput

错误信息:

Text.prototype.render undefined

解决:

Text.prototype.render
改为
Text.render

create-react-class

错误信息:

Module create-react-class does not exist in the Haste module map

解决:
由于把第三方库引入本地,代码老旧,新版已不支持create-react-class的方式,所以逐个改造为es6的语法

7.Android上的修改

解决完上面的问题,在iOS上就可以正常的跑起来了,但在Androidbuild都过不了。
想到客户端同学之前提到的一个坑:

 //解决同一个库依赖不同的版本 例如react-native 有0.49.5 有的是+ 统一成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"
                }
            }
        }
    }

他们需要把依赖的库统一版本,于是把上述的0.49.5改为0.56.0

 //解决同一个库依赖不同的版本 例如react-native 有0.56.0 有的是+ 统一成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,成功了,但启动后马上Crash,打开AndroidStudio发现有错误信息:


解决:将这些项目android文件下的 ***.iml 文件删掉,重新编译
错误信息没有了,但启动依旧Crash,这时候和客户端同学沟通可能是so库的问题,于是替换了so库(这里有一个小技巧,要获得一个新版本的so库,可以通过创建一个新版本的Demo,然后从中获取),依旧出错,但错误信息变了:

java.lang.NoClassDefFoundError: Failed resolution of: Lcom/facebook/common/soloader/SoLoaderShim;

通过Google大致猜测是gif库出了问题

 //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,重新编译运行,一切正常。

8.Android Jenkins 打包失败

错误信息:


解决:
这个问题相当奇葩,几乎找不到思路,试过删除目录,再拉代码、拉库都无效,最后是在react-native bundle命令加中增加一个--reset-cache参数,清除打包的缓存文件,终于可以了。

9.Android Code-Push错误

错误信息(issue):

facebook::react::Recoverable: Could not open file ReactNativeDevBundle.js: No such file or directory

解决:
暂时还未解决,code-push的代码中可以看到一段注释说明解决代码的片段,但实际仍未解决,不过好在只出现在本地开发模式,这个还需继续跟进。

三、总结

1.看升级日志

升级前,建议看一遍官方的升级日志,这样可以对碰到的问题有预期和解决方向。

2.勤升级

有精力的话,建议更勤快的升级,这样每次升级带来的问题不会那么多,而且通过特定版本的升级日志通常就能定位问题。像这次跨多版本的升级,中间涉及的错误修复可能需要你仔细阅读多个版本的升级日志,困难度增大不少。

3.谨慎选择第三方库

对于第三方库,除了高star,还要注意它的更新频率。
如果在更新时碰到第三方库出错并很长时间都无人维护了,可通过下面几种办法解决:

  • Fork一份,修改代码,自己发npm或者引用fork地址;
  • 本地新建一个组件,利用继承的方式,修改源码,引用本地的新组件;
  • 把GitHub上的代码直接放在本地维护。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,198评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,663评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,985评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,673评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,994评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,399评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,717评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,407评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,112评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,371评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,891评论 1 256
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,255评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,881评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,010评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,764评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,412评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,299评论 2 260

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,544评论 25 707
  • 用两张图告诉你,为什么你的 App 会卡顿? - Android - 掘金 Cover 有什么料? 从这篇文章中你...
    hw1212阅读 12,459评论 2 59
  • 今天,没有听微课,没有艾灸。很颓废。给木泽做了一个蛋糕。 给他做蛋糕的时候,决定还是买一个吧。自己的难日,何必为难...
    馨儿妈阅读 247评论 0 0
  • https://docs.python.org/3/library/functions.html 内置的基本函数语...
    laughingsolo阅读 439评论 0 0
  • 第14天 · 21天告别拖延 #玩卡不卡·每日一抽# 每一位都可以通过这张卡片觉察自己: 1、直觉他叫什么名字?...
    张梦格阅读 199评论 0 0