You are here
Home > Technology > react-native > Step by step instructions on Upgrading React Native to 0.60.4

Step by step instructions on Upgrading React Native to 0.60.4

There are many breaking changes in 0.60 and migrating from 0.59.x could be a nightmare if not done right. You’ll encounter different errors and in the process of exploring community responses, you might add more issues. This is a SETP-by-SETP guide on migrating directly to 0.60.5 from 0.59.1. Even if you aren’t using these versions precisely, this article will help you to upgrade to 0.60.5

How to follow?

Move through implementing steps and pay special attention to the file name and folders. Note: – Any strike-through line means to remove that text – Bold text means this change is specific to upgrade – I’ve included changes for react-native-vector-icon and react-native-gesture-handler as well as they are commonly used and needs to be in sync with react native version. If you aren’t using them, ignore related changes.

Am I prepared?

If you have a working application using 0.59.1, you’re good. I expect you to have done changes like upgrading .flowconfig version to around 0.92.0 and also would have renamed .babelrc to babel.config.js. If you are struggling with upgrading to 0.59.1 from an older version, add a comment and I’ll help. Let’s Upgrade!!!!!

Step-1: Update package.json

Those in bold should either be updated (if you have older version) or be added if they already don’t exist. react-native-gesture version should be upgraded if you’re using it else simply ignore it.
 "dependencies": {
      "axios": "^0.18.0",
      "react": "16.8.6",
      "react-native": "0.60.5",    
      "react-native-gesture-handler": "^1.4.1",
 
.... 

    "devDependencies": {
     "@babel/core": "^7.6.0",
     "@babel/runtime": "^7.6.0",
     "@react-native-community/eslint-config": "^0.0.5",
     "babel-jest": "^24.9.0",
     "eslint": "^6.4.0",
     "jest": "^24.9.0",
     "metro-react-native-babel-preset": "^0.56.0",
     "react-test-renderer": "16.8.6"
    },

Step-2: Update android/build.gradle

Make sure your build.grade is similar to below. Ideally, it should be same as below with any custom addition you may have made.
 
buildscript {
    ext {
        buildToolsVersion = "28.0.3"
        minSdkVersion = 16
        compileSdkVersion = 28
        targetSdkVersion = 28
        supportLibVersion = "28.0.0"
    }
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.4.1'
 
    }
}

allprojects {
    repositories {
        mavenLocal()
        maven {
            // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
            url("$rootDir/../node_modules/react-native/android")
        }
        maven {
            // Android JSC is installed from npm
            url("$rootDir/../node_modules/jsc-android/dist")
        }

        google()
        jcenter()
    }
}

Step-3: Update .flowconfig

Make sure your build.grade (inside app folder) is similar to below. Ideally, it should be same as below with any custom addition you may have made.
[ignore]
 ....
 [include]
 [libs]
 node_modules/react-native/Libraries/react-native/react-native-interface.js
 node_modules/react-native/flow/
 node_modules/react-native/flow-github/
 [options]
 ....
 [version]
 ^0.92.0
  

Step-4: Add build_defs.bzl

Add file names build_defs.bzl to the android/app/ folder with the following content
"""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,
         )
  

Step-5: Add AndroidManifest.xml

This is a different location I’m talking about than the one you are aware of 🙂 Create a folder debug inside app/src/ and add AndroidManifest.xml with the following code
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

    <application android:usesCleartextTraffic="true" tools:targetApi="28" tools:ignore="GoogleAppIndexingWarning" />
</manifest>


  

Step-6: Update AndroidManifest.xml

Open up AndroidManifest.xml inside app/src/main and make changes as shown below
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="YOUR_PACKAGE_NAME">

    <uses-permission android:name="android.permission.INTERNET" />
       <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> 

    <application
      android:name=".MainApplication"
      android:label="@string/app_name"
      android:icon="@mipmap/ic_launcher"
      android:roundIcon="@mipmap/ic_launcher_round"
      android:allowBackup="false"
      android:theme="@style/AppTheme">
     ...
      <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
    </application>

</manifest>

Step-7: Update Gradle Properties

Open gradle-wrapper.properties inside android/gradle/wrapper/ and make the following changes
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

Step-8: Remove libRCTGeoLocation.a

One problem I faced while trying to run build on iOS was related to the presence of this library which was required earlier but now isn’t needed and is taken care of by other frameworks. You can either remove it by opening Xcode (image below) OR simply open /ios/project_name.xcodeproj/project.pbxproj in text editor and remove the two occurrences of libRCTGeoLocation
    00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */; };

            00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */,

Step-9: Update build.gradle

This is different than the one you fixed above. Make the following changes to build.gradle inside android/app/ folder
apply plugin: "com.android.application"

import com.android.build.OutputFile
....
/**
 * The preferred build flavor of JavaScriptCore.
 *
 * For example, to use the international variant, you can use:
 * `def jscFlavor = 'org.webkit:android-jsc-intl:+'`
 *
 * The international variant includes ICU i18n library and necessary data
 * allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that
 * give correct results when using with locales other than en-US.  Note that
 * this variant is about 6MiB larger per architecture than default.
 */
def jscFlavor = 'org.webkit:android-jsc:+'

/**
 * Whether to enable the Hermes VM.
 *
 * This should be set on project.ext.react and mirrored here.  If it is not set
 * on project.ext.react, JavaScript will not be compiled to Hermes Bytecode
 * and the benefits of using Hermes will therefore be sharply reduced.
 */
def enableHermes = project.ext.react.get("enableHermes", false);

android {
    compileSdkVersion rootProject.ext.compileSdkVersion
    buildToolsVersion rootProject.ext.buildToolsVersion
    
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    defaultConfig {
        applicationId "com.YOUR_PROJECT_NAME"
        minSdkVersion rootProject.ext.minSdkVersion
        targetSdkVersion rootProject.ext.targetSdkVersion
        versionCode 1
        versionName "1.0"
    }
    splits {
        abi {
            reset()
            enable enableSeparateBuildPerCPUArchitecture
            universalApk false  // If true, also generate a universal APK
            include "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
        }
    }
    signingConfigs {
        debug {
            storeFile file('debug.keystore')
            storePassword 'android'
            keyAlias 'androiddebugkey'
            keyPassword 'android'
        }
    }
    buildTypes {
        debug {
            signingConfig signingConfigs.debug
        }
        release {
            // Caution! V÷Öû%§æOv#´û%§
Ï€ıˇˇˇˇIn production, you need to generate your own keystore file.
            // see https://facebook.github.io/react-native/docs/signed-apk-android.
            signingConfig signingConfigs.debug
            minifyEnabled enableProguardInReleaseBuilds
            proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
        }
    }
    // applicationVariants are e.g. debug, release
    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            // For each separate APK per architecture, set a unique version code as described here:
            // http://tools.android.com/tech-docs/new-build-system/user-guide/apk-splits
            def versionCodes = ["armeabi-v7a":1, "x86":2, "arm64-v8a": 3]
            def abi = output.getFilter(OutputFile.ABI)
            if (abi != null) {  // null for the universal-debug, universal-release variants
                output.versionCodeOverride =
                        versionCodes.get(abi) * 1048576 + defaultConfig.versionCode
            }
        }
    }
     // applicationVariants are e.g. debug, release
    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            // For each separate APK per architecture, set a unique version code as described here:
            // https://developer.android.com/studio/build/configure-apk-splits.html
            def versionCodes = ["armeabi-v7a": 1, "x86": 2, "arm64-v8a": 3, "x86_64": 4]
            def abi = output.getFilter(OutputFile.ABI)
            if (abi != null) {  // null for the universal-debug, universal-release variants
                output.versionCodeOverride =
                        versionCodes.get(abi) * 1048576 + defaultConfig.versionCode
            }

        }
    }

      packagingOptions {
        pickFirst '**/armeabi-v7a/libc++_shared.so'
        pickFirst '**/x86/libc++_shared.so'
        pickFirst '**/arm64-v8a/libc++_shared.so'
        pickFirst '**/x86_64/libc++_shared.so'
        pickFirst '**/x86/libjsc.so'
        pickFirst '**/armeabi-v7a/libjsc.so'
    }
}



dependencies {
    implementation project(':react-native-gesture-handler')
    implementation fileTree(dir: "libs", include: ["*.jar"])
    implementation "com.android.support:appcompat-v7:${rootProject.ext.supportLibVersion}"
    implementation "com.facebook.react:react-native:+"  // From node_modules
    compile project(':react-native-vector-icons')
    
    if (enableHermes) {
      def hermesPath = "../../node_modules/hermesvm/android/";
      debugImplementation files(hermesPath + "hermes-debug.aar")
      releaseImplementation files(hermesPath + "hermes-release.aar")
    } else {
      implementation jscFlavor
    }
}



apply from: file("../../node_modules/react-native-vector-icons/fonts.gradle")

// Run this once to be able to run the application with BUCK
// puts all compile dependencies into folder libs for BUCK to use
task copyDownloadableDepsToLibs(type: Copy) {
    from configurations.compile
    into 'libs'
}


 

Last Steps

I hope it was easy. Next Steps: 1. Remove Node-Modules folder 2. run yarn install 3. run react-native run-ios OR react-native run-android If you encounter any errors OR if it was a smooth execution, share in comments. Thanks!
0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
Top
0
Would love your thoughts, please comment.x
()
x