Bite AI Logo

Yet Another Article About Upgrading React Native

Upgrading React Native is a pain but a necessary part of having a deployed app. React Native in 0.59.0 will improve the process by automating the patching process. Patching the project files is one part of multiple steps required to upgrade successfully without breaking an app.

The steps I came up with have come out of upgrading from 16 releases, 0.42.1 to 0.57.0, in a couple of weeks. This felt like an incredibly daunting task because my project uses about 15 native dependencies for things ranging from icons to the camera.

I started by Googling around and read how other people approached upgrading. One solution which seemed appealing was to create a fresh project and pasting the code in. I felt this was not the right approach because I may not see a functioning project on iOS or Android for days because there had been too many breaking changes in React Native and the dependencies I use.

The process I chose instead was to create a branch per major release and upgrade by each dot release in the branch. The steps I took:

  1. Read React Native Release information to find deprecations and breaking changes

  2. Upgrade the project using react-native-git-upgrade [version]
  3. Run my post upgrade script
  4. Handle build errors. Google and Github Issues are your friend here. Most errors have been extensively discussed and many discussions include workarounds. Sometimes you will need to locally patch files to get the project compiling.
  5. Acceptance test. This took ~ 1 minute per platform. Automating the testing using Detox will significantly speed up this step. I wish I had done this before starting.
  6. Fix warnings. When you manually go through your app you'll see depreciation notices and warnings.

The rest of the post provides details and the scripts for some of steps.

React Native Upgrade

The basic instructions are on the React Native Docs. I modified react-native-git-upgrade tool with the commit so it will suggest git apply when a merge conflict arises when upgrading the templates.

This soon will be changing to react-native upgrade [verison], more info.

Post Upgrade Script

The script builds and installs the app on iOS and Android. It uses say to notify you incase you are doing something else while compiling.

#!/usr/bin/env bash
set -e
set -x

exec >> build.log 2>&1

pushd /Users/vinayan3/Workspace/app-react

npm install

pushd ios
rm -f Podfile.lock
fastlane localBuild
popd

pushd /Users/vinayan3/Library/Developer/Xcode/DerivedData/
xcrun simctl install booted   `ls -t | grep  "AppReact" | head -1`/Build/Products/Debug-iphonesimulator/AppReact.app
popd

say "iOS Done"

pushd android
./gradlew installDebug
popd

say "Android Done"

Locally Patching Files

There are times where you have to patch or fork native dependencies because a project is no longer accepting pull requests. I used the postinstall step in package.json to handle these cases. Below is an example of patching a dependency.

Package.json

{
 "version": "0.0.1",
 "private": true,
 "scripts": {
   "postinstall": "./scripts/react-native-spinkit-android-build-patch.sh"
  }
}

Script Source

#!/usr/bin/env bash

set -e

pushd node_modules/react-native-spinkit

SEMAPHORE=android_build_patched
if test ! -f ${SEMAPHORE}; then
 touch ${SEMAPHORE}
 PATCH_FILE=android_build.patch
 curl https://patch-diff.githubusercontent.com/raw/maxs15/react-native-spinkit/pull/103.patch > ${PATCH_FILE}
 patch -p1 <${PATCH_FILE}
 rm ${PATCH_FILE}
fi

popd

iOS

I use fastlane on the project and I added a step to build for the simulator.

  lane :localBuild do
     cocoapods
     xcbuild(
     scheme: "AppReact",
     configuration: "Debug",
     xcargs: "-sdk iphonesimulator -destination='name=iPhone 8,OS=12.1'")
     scan(scheme: "AppReact", device: test_device, skip_slack: true)
  end

If you are not using Pods for native dependencies I highly recommend switching. It’s made upgrading significantly easier because manually editing XCode pbxproject files is not easy. Pod install also has sanity checks on the XCode project which ensures the upgrade process isn't adding in files or outputs which don't exist.

Dependencies

I avoided upgrading dependencies until I encountered a build error, app crash, or warning message. The best solution to fix this was to find the release of the dependency closest to the React Native release on Github. More often than not Github Issues discussing a fix to support React Native versions.

After I got to the latest version of React Native I began upgrading all the dependencies to the latest. NCU is a wonderful tool for for finding and upgrading to the latest versions of npm packages.

Post Thoughts

Upgrading React Native won’t be as bad as you think. However, it's still a manual process which can be improved by having tools which can find and edit your code for breaking changes. Another improvement could be a tool like NCU which can recommend which version of a dependency you should use based on your React Native version.