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:
Read React Native Release information to find deprecations and breaking changes
react-native-git-upgrade [version]
The rest of the post provides details and the scripts for some of steps.
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.
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"
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.
{
"version": "0.0.1",
"private": true,
"scripts": {
"postinstall": "./scripts/react-native-spinkit-android-build-patch.sh"
}
}
#!/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
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.
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.
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.