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",
}
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"]
}
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
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'
}
}
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
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"
}
}
}
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]
}
}
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"
}
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"]))
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,
)
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"
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"
}
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.
Top comments (0)