How to Upgrade from React Native 0.57 to 0.59 | Part 1: Upgrading to 0.58

julietter

JulietteR

Posted on July 29, 2019

How to Upgrade from React Native 0.57 to 0.59 | Part 1: Upgrading to 0.58

Hey you! You need to upgrade to 0.59! 📢

If you haven’t already heard, all React Native apps will need to be upgraded to 0.59 by August 01, 2019 if you wish to submit updates to the Google Play store. This is due to a new 64-bit requirement set forth by Google Play. They're pretty serious about it:

By August 1, 2019, all apps that use native code must provide a 64-bit version in addition to the 32-bit version in order to publish an update. This past January, we reiterated that this is required in order to make way for innovation and in anticipation of future Android devices that only support 64-bit code.

Lucky for us, React Native has introduced 64-bits builds in their 0.59 release. The problem, though, is that it can be a little tricky to update. That’s why I created this tutorial. Follow along if you want to get your app up the speed and future-proofed for upcoming releases as well.

About This Tutorial

In my situation, I needed to upgrade a project from 0.57.4 to 0.59.8 (Note: A newer 0.59.10 has since been released). I also required both an Android and an iOS build.

When bumping a project up by two minor versions, I highly suggest upgrading one minor version at a time. (e.g. 0.57 to 0.58, then 0.58 to 0.59). It eases troubleshooting if something goes wrong.

So if you need to climb up from 0.57 like I did, I present to you Part 1 of 2: Upgrading to 0.58!

Part 1: Upgrading to React Native 0.58 ⬆️

🔑 Key Changes

  • The iOS JavaScriptCore framework now needs to be linked to our app.
  • Android’s target 27 SDK is now supported.

Step 1: Update your package.json ⬆️

Open up your package.json and update the following dependencies:

// package.json

"dependencies": {
     "react": "16.6.3",
     "react-native": "0.58.6",
},
"devDependencies": {
     "babel-core": "^7.0.0-bridge.0",
     "react-test-renderer": "16.6.3",
}
Enter fullscreen mode Exit fullscreen mode

Then, delete your node_modules and reinstall a fresh batch with npm i.

Step 2: Modernize Babel đź—Ł

See that Babel upgrade above? Version 7 introduced a new type of Babel config file that is now much preferred, and even required by many libraries that you may use.

To update:

1. Create a new babel.config.js file.

2. Port over any configs you may have in your current .babelrc file. These presets will now need to be exported, like in the example below.

// a basic react native babel.config.js

module.exports = {
     presets: ["module:metro-react-native-babel-preset"]
}
Enter fullscreen mode Exit fullscreen mode

3. Once done, delete your old .babelrc file.

Step 3: Update Flow ⬆️

Here’s an easy one. Open .flowconfig and update the flow dependency:

// .flowconfig

[version]
^0.92.0
Enter fullscreen mode Exit fullscreen mode

If you use Flow and run into errors after this update, head over to their changelog to diagnose any issues.

Step 4: Link the JavaScriptCore Framework đź”—

1. Open up your XCode project.

2. Select your project:

3. Select your project’s main target settings:

4. Navigate into the Build Phases screen:

5. Under Link Binary With Libraries, add the JavaScriptCore.framework

Be aware that you may need to clean your XCode caches after this change. Here’s an article that can help with that.

Step 5: Update android/build.gradle ⬆️

Update android/build.gradle to support some new libraries/SDKs. Don’t delete anything, just update the following version numbers:

// android/build.gradle

buildscript {
     ext {
          buildToolsVersion = "28.0.2"
          compileSdkVersion = 28
          targetSdkVersion = 27
          supportLibVersion = "28.0.0"
     }

     dependencies {
          classpath 'com.android.tools.build:gradle:3.2.1'
     }

     task wrapper(type: Wrapper) {
          gradleVersion = '4.7'
     }
}
Enter fullscreen mode Exit fullscreen mode

Step 6: Update Gradle ⬆️

Using the new Gradle version of 4.7 (updated in the previous step) will require you to update android/gradle/wrapper/gradle-wrapper.properties

distributionUrl=https\://services.gradle.org/distributions/gradle-4.7-all.zip
Enter fullscreen mode Exit fullscreen mode

Step 7: Update android/app/build.gradle ⬆️

In 0.58, React Native started to introduce 64-bit Android builds. To add this build type:

1. First, remove the ndk section. It will no longer be used:

android {
     defaultConfig {
          // Remove the following:
          ndk {
               abiFilters "armeabi-v7a", "x86"
          }
     }
}
Enter fullscreen mode Exit fullscreen mode

2. Add the “arm64-v8a” architecture to the following lists:

android {
  splits {
    abi {
      include "armeabi-v7a", "x86", "arm64-v8a"
    }
  }
  buildTypes {
    variant.outputs.each { output ->
      def versionCodes = ["armeabi-v7a":1, "x86":2, "arm64-v8a": 3]
    }
  }
Enter fullscreen mode Exit fullscreen mode

3. Finally, since we are only upgrading to React Native 0.58.6, we must specify the React Native dependency that Android should use:

dependencies {
     // implementation "com.facebook.react:reactnative:+"
     implementation "com.facebook.react:react-native:0.58.6"
}
Enter fullscreen mode Exit fullscreen mode

Step 8: Change Up Android Build Scripts 🚧

For those that use Buck, the build scripts have changed a bit:

1. In android/app/BUCK, replace the for jarfile/for aarfile loops with the following:

### OLD CODE
lib_deps = []

for jarfile in glob(['libs/*.jar']):
  name = 'jars__' + jarfile[jarfile.rindex('/')+ 1: jarfile.rindex('.jar')]
  lib_deps.append(':' + name)
  prebuilt_jar(
    name = name,
    binary_jar = jarfile,
  )

for aarfile in glob(['libs/*.aar']):
  name = 'aars__' + aarfile[aarfile.rindex('/') + 1: aarfile.rindex('.aar')]
  lib_deps.append(':' + name)
  android_prebuilt_aar(
    name = name,
    aar = aarfile,
 )

### NEW CODE
load(":build_defs.bzl", "create_aar_targets", "create_jar_targets")

lib_deps = []

create_aar_targets(glob(["libs/*.aar"]))

create_jar_targets(glob(["libs/*.jar"]))
Enter fullscreen mode Exit fullscreen mode

2. Now, create a new android/app/build_defs.bzl file:

# android/app/build_defs.bzl

"""Helper definitions to glob .aar and .jar targets"""
def create_aar_targets(aarfiles):
    for aarfile in aarfiles:
        name = "aars__" + aarfile[aarfile.rindex("/") + 1:aarfile.rindex(".aar")]
        lib_deps.append(":" + name)
        android_prebuilt_aar(
            name = name,
            aar = aarfile,
        )
def create_jar_targets(jarfiles):
    for jarfile in jarfiles:
        name = "jars__" + jarfile[jarfile.rindex("/") + 1:jarfile.rindex(".jar")]
        lib_deps.append(":" + name)
        prebuilt_jar(
            name = name,
            binary_jar = jarfile,
        )
Enter fullscreen mode Exit fullscreen mode

Step 9: Check Your Refs đź‘€

<ScrollView>, <CameraRollView>, and <SwipeableRow> all got some updates that may cause you trouble if you use any refs in these components.

This wasn’t an issue in my project, but if it is for you, using createRef() for these components should get you on your way. More info can be found here.

Step 10: New Round Android Icons! đź‘Ź

Last but not least, round Android icons are now supported! Here’s a great article on how to create these. Once you’ve created these files, add them to your android/app/src/main/AndroidManifest.xml file:

<manifest...
     <application...
          android:roundIcon="@mipmap/ic_launcher_round"
Enter fullscreen mode Exit fullscreen mode

Step 11: Test, Test, Test 🧪

Build your apps. Make sure to run them on actual iOS and Android devices. See any new deprecation warnings? Best to nip them in the bud right now. Some of these warnings may be coming from your dependencies. See if there are any updates out there. If not, you may need to patch things yourself.

Patching Packages đźš‘

Need to patch a package? My favorite way to do this is with patch-package. This is a library that diffs changes you made to a node_modules package, saves those changes, and applies those changes every time you run npm i. Here’s a quick tutorial:

1. Run npm i patch-package

2. Add this post-install script to your package.json:

"scripts": {
     "postinstall": "patch-package"
}
Enter fullscreen mode Exit fullscreen mode

3. Head into your node_modules and make whatever changes you need to your target dependency.

4. Once done, run npx patch-package package-name. This will create a patch file for that particular package. You should commit these files to your project.

5. Now, anytime you delete your node_modules, your patch(es) will get added after you run npm i. 🙌

Next Steps

Got 0.58 working for your project? Congrats! 🎉 You’re halfway there!

Stayed tuned for Part 2: Upgrading to React Native 0.59!

👋 Hi! I’m Juliette. I work at Eventric as a Software Developer. Come follow me on Twitter at @Juliette.

đź’– đź’Ş đź™… đźš©
julietter
JulietteR

Posted on July 29, 2019

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related