React Native 0.60升级指南

Hermes

虽说每次大版本升级都是一次煎熬,不过如果落下一次下次就更艰难了,何况这一次还有听起来很NB的Hermes

差异比对修改

这次ReactNative很贴心上了Upgrade Helper项目,终于不用再自己去新建一个模版工程来人肉比对差异了。

js端

由0.59.x升级上来,js端只需要修改package.json中的包版本,以及.flowconfig .eslintrc.js两个配置文件就好了

Android端

0.60版本一大特点之一就是引入了自动链接,不用再像往常一样执行react-native link或是人肉修改app/build.gradle跟settings.gradle文件

  1. 执行[react-native run-android],根据提示,使用[react-native unlink xxx]移除之前在文件中链接的库
  2. 修改settings.gradle,加入

    1
    apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
  3. 修改app/build.gradle,加入

    1
    apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
  4. 考虑到这次RN版本升级时间还不长,部分第三方包对自动链接的兼容性不好,可以在项目根目录新建react-native.config.js文件,指定不需要进行自动链接,仍然采取原本手工链接方式的库

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    module.exports = {
    dependencies: {
    'react-native-navigation': {
    platforms: {
    android: null,
    ios: null,
    }
    },
    },
    };
  5. 原本MainApplication中的库导入被自动生成PacakgeList替代,不过自己实现的Native代码还是需要在后面进行追加。

  除此之外,本次另一重大升级就是加入了AndroidX的支持

  1. 在gradle.properties中加入

    1
    2
    android.useAndroidX=true
    android.enableJetifier=true
  2. AndroidStudio中选择ReFactor –> Migrate to AndroidX… 然后根据提示操作,能够自动搞定app/build.gradle中的包引入替换,不过代码中的类import语句就需要自己根据报错来修改了。

iOS端

因为没有AndroidX升级这档子事,不需要涉及到源码的修改

  1. 清空Libraries目录下库引用
  2. 修改Podfile,加入“use_native_modules!”

    1
    2
    3
    4
    5
    target 'xxx'  do
    pod xxxx
    ...
    use_native_modules!
    end
  3. 执行cd ios; pod install,查看日志确认需要的第三方库是否都有正常引用,没有的话可以检查第三方库ios目录下是否有xxx.podspec文件,如果没有的话可以在Podfile中手工导入

一些第三方库

react-native-vector-icons

取决于使用的版本,至少安装目前最新版本来说会提示“Unrecognized font family ‘Material Icons’”

  1. 修改Info.plist,加入

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    <key>UIAppFonts</key>
    <array>
    <string>AntDesign.ttf</string>
    <string>Entypo.ttf</string>
    <string>EvilIcons.ttf</string>
    <string>Feather.ttf</string>
    <string>FontAwesome.ttf</string>
    <string>FontAwesome5_Brands.ttf</string>
    <string>FontAwesome5_Regular.ttf</string>
    <string>FontAwesome5_Solid.ttf</string>
    <string>Foundation.ttf</string>
    <string>Ionicons.ttf</string
    <string>MaterialCommunityIcons.ttf</string>
    <string>MaterialIcons.ttf</string>
    <string>Octicons.ttf</string>
    <string>SimpleLineIcons.ttf</string>
    <string>Zocial.ttf</string>
    </array>
  2. 修改app/build.gradle,在最后加入

    1
    apply from: "../../node_modules/react-native-vector-icons/fonts.gradle"

react-native-vector-icons

修改android/build.gradle,加入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
subprojects { subproject ->
afterEvaluate {
if ((subproject.plugins.hasPlugin('android') || subproject.plugins.hasPlugin('android-library'))) {
android {
compileSdkVersion rootProject.ext.compileSdkVersion
buildToolsVersion rootProject.ext.buildToolsVersion
variantFilter { variant ->
def names = variant.flavors*.name
// To check for a certain build type, use variant.buildType.name == "<buildType>"
if (
names.contains("reactNative51") ||
names.contains("reactNative55") ||
names.contains("reactNative56") ||
names.contains("reactNative57") ||
names.contains("reactNative57WixFork") ||
names.contains("reactNative57_5")
) {
// Gradle ignores any variants that satisfy the conditions above.
setIgnore(true)
}
}
}
}
}
}

开启Hermes

根据AppStore的协议

3.3.2 — An Application may not itself install or launch other executable code by any means, including without limitation through the use of a plug-in architecture, calling other frameworks, other APIs or otherwise. No interpreted code may be downloaded or used in an Application except for code that is interpreted and run by Apple’s Documented APIs and built-in interpreter(s).

iOS暂时是没什么指望用上Hermes了,Android开启比较简单,只需要修改app/build.gradle,然后clean重新编译即可

1
2
3
4
project.ext.react = [
entryFile: "index.js",
enableHermes: true, // clean and rebuild if changing
]

不过在运行时会遇到

1
java.lang.UnsatisfiedLinkError: couldn't find DSO to load: librealmreact.so caused by: dlopen failed: library "libjsc.so" not found

好吧,Realm依然需要JavaScriptCore的库,不过至少说是未来的数月已经有计划要迁移,好像除了等也没啥办法了……