前言
公司项目 ReactNative 版本比较旧,因此想要升级。
升级版本为 : 0.41.1->0.55.4 。
升级过程中遇到了一个问题。
React Native报错 unddefined is not an object(evaluating ‘_reactnative.propTypes’)。
错误原因
在给 React 16 中有一个大的改变,PropTypes的代码从React中分离出来了,放在一个独立的 npm包 prop-types里。
也就是说,之前的这种写法已经不能再使用了。
之前的 :
import { PropTypes } from 'react'
需要改变为 :
import PropTypes from 'prop-types'
当然,有的人会说,如果是第三库直接升级第三库就可以了。有两个问题 :
1. 有的第三方库已经不再维护了。
2. 你能保证新版库没有什么坑爹的 Bug 吗 ? 大量的第三方库一次性升级,非常的不稳定。
问题
如果你的项目比较大,不仅自己的类使用到了 PropTypes , 你依赖的第三方库也使用到了 PropTypes 。该怎么办呢 ?
比如 : 第三库 react-native-view-transformer :
import React from 'react';
......
ViewTransformer.propTypes = {
enableTransform: React.PropTypes.bool,
enableScale: React.PropTypes.bool,
enableTranslate: React.PropTypes.bool,
maxOverScrollDistance: React.PropTypes.number,
maxScale: React.PropTypes.number,
contentAspectRatio: React.PropTypes.number,
enableResistance: React.PropTypes.bool,
onViewTransformed: React.PropTypes.func,
onTransformGestureReleased: React.PropTypes.func
};
当然你可以一个个手动去改,但是依赖库那么多,如果一个个改的话,估计人都要累死了。
解决方法
如果类都是自己写的话,直接全局查找 PropTypes 即可。
而第三方库都在 node_modules 文件夹内 , 如果想要排查第三方的 PropTypes ,可以使用以下 Unix 命令 ,找出所有使用到 PropTypes 的库:
在 node_modules 的父目录执行下列命令。
find ./node_modules -type f -print0 | xargs -0 grep 'PropTypes' | cut -d/ -f3 | sort | uniq | xargs -I{} grep -L 'prop-types' ./node_modules/{}/package.json
windows 可以使用 Git Bash 调用上方命令。调用结果 :
我们看到这些第三方库使用到了 PropTypes 。 有没有什么简单的方法,一次性改掉这些文件的 PropTypes 呢 ?
使用 react-codemod 来重构 JavaScript 代码 。
库地址 : https://github.com/reactjs/react-codemod 。
使用方法 : (来自 react-codemod 的 issue )
1. npm install -g jscodeshift
2. git clone https://github.com/reactjs/react-codemod.git
3. cd react-codemod
4. npm install (我执行这一步的时候报错了,不过我直接忽略了…)
5. 切换到你想要转换的目录,执行下列命令 :
jscodeshift -t react-codemod/transforms/React-PropTypes-to-prop-types.js <path>
第五步,我给大家举个例子 :
以我上方的需要转换的文件为例 ,我要改动 react-native-view-transformer 文件夹下所有的类,你可以执行。
jscodeshift -t react-codemod/transforms/React-PropTypes-to-prop-types.js node_modules/react-native-view-transformer
文件路径大家注意写正确哦 ! 不要直接复制粘贴。
执行结果显示如下 :
意思是有1个文件转换成功了。
总结
升级版本的过程中,大家不免将很多代码迁移到下一代 JavaScript。
react-codemod 有很多解决方法 ,大家可以参考下 :
facebook 官方也有个库 https://github.com/facebook/jscodeshift 。
最后 :
鉴于 RN 在Android 平台上糟糕的性能表现。如果你没入坑,千万不要跳进来。讲道理,修复那些 RN Bug 的时间足够我重新用原生写 Android 和 Ios 的代码。