Skip to content

Commit

Permalink
Upgrade to react-native 0.69 (#18006)
Browse files Browse the repository at this point in the history
# Why

for sdk 46
close ENG-5353

# How

- update packages 
  - react -> 18.0.0
  - react-native -> 0.69.0
  - react-dom -> 18.0.0
  - react-native-web -> ~0.18.1
  - react-test-renderer -> ~18.0.0
  - @types/react -> ~18.0.14
  - @types/react-native -> ~0.69.1
- early patch react-native for 0.69.1 fixes
  - facebook/react-native@43f831b
  - facebook/react-native@c2088e1
  - facebook/react-native@f97c6a5
  - facebook/react-native@79baca6
  - facebook/react-native#34064 (comment)
- migrate `expo-template-bare-minimum`, `bare-expo`, `bare-sandbox` to 0.69. reference from https://react-native-community.github.io/upgrade-helper/?from=0.68.1&to=0.69.0
  - also remove the `hermesCommand` because 0.69 uses the builtin hermes-engine
- `expo-av`, `expo-modules-core`, `expo-gl-cpp`: fix android cpp building errors, because 0.69 ships both release and debug aar
- `expo-dev-client`: fix android build error from RedBox package rename
-  `html-elements`: update RNWView where react-native-web removed [the `css` import](necolas/react-native-web@b27c9820)
- `expo`: move Expo.podspec out from ios, because newer [rn-cli removed the `podspecPath` and `project` support](react-native-community/cli@25eec7c#diff-0dddbcedebb33032fcac5991f3dcdfa44157e6ae87afcf3dabcd240a0db09832L58).
- [ ] disable dev-client because the vendored reanimated in dev menu doesn't support 0.69 yet, e.g. `folly_json -> folly_runtime`
- update reanimated and gesture-handler to latest for 0.69 support
- `jest-expo`: update to [fix the deprecated react-native-web jest preset](necolas/react-native-web@9b0c119)
- `NCL`, `home`, patch `react-native-svg`: fix react 18 that [`children` should be explicitly added](https://reactjs.org/blog/2022/03/08/react-18-upgrade-guide.html#updates-to-typescript-definitions)
- `@expo/cli` fix react-native-web and react-dom version checks

# Test Plan

- android bare-expo smoke test
- ios bare-expo smoke test
- ci passed
  - updates e2e is broken because in the flow the react-native doesn't include 0.69.1 fixes.
  • Loading branch information
Kudo committed Jun 29, 2022
1 parent 39f960e commit dec397f
Show file tree
Hide file tree
Showing 116 changed files with 2,147 additions and 1,096 deletions.
28 changes: 18 additions & 10 deletions apps/bare-expo/android/app/build.gradle
Expand Up @@ -79,15 +79,16 @@ import org.apache.tools.ant.taskdefs.condition.Os

def projectRoot = rootDir.getAbsoluteFile().getParentFile().getAbsolutePath()

def reactNativeRoot = new File(["node", "--print", "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim()).getParentFile().getAbsolutePath()

project.ext.react = [
entryFile: ["node", "-e", "require('expo/scripts/resolveAppEntry')", projectRoot, "android"].execute(null, rootDir).text.trim(),
enableHermes: (findProperty('expo.jsEngine') ?: "jsc") == "hermes", // clean and rebuild if changing
cliPath: new File(["node", "--print", "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim()).getParentFile().getAbsolutePath() + "/cli.js",
hermesCommand: new File(["node", "--print", "require.resolve('hermes-engine/package.json')"].execute(null, rootDir).text.trim()).getParentFile().getAbsolutePath() + "/%OS-BIN%/hermesc",
composeSourceMapsPath: new File(["node", "--print", "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim()).getParentFile().getAbsolutePath() + "/scripts/compose-source-maps.js",
enableHermes: (findProperty('expo.jsEngine') ?: "jsc") == "hermes",
cliPath: "${reactNativeRoot}/cli.js",
composeSourceMapsPath: "${reactNativeRoot}/scripts/compose-source-maps.js",
]

apply from: new File(["node", "--print", "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim(), "../react.gradle")
apply from: new File(reactNativeRoot, "react.gradle")

/**
* Set this to true to create two separate APKs instead of one:
Expand Down Expand Up @@ -173,8 +174,9 @@ android {
"NDK_TOOLCHAIN_VERSION=clang",
"GENERATED_SRC_DIR=$buildDir/generated/source",
"PROJECT_BUILD_DIR=$buildDir",
"REACT_ANDROID_DIR=$rootDir/../node_modules/react-native/ReactAndroid",
"REACT_ANDROID_BUILD_DIR=$rootDir/../node_modules/react-native/ReactAndroid/build"
"REACT_ANDROID_DIR=${reactNativeRoot}/ReactAndroid",
"REACT_ANDROID_BUILD_DIR=${reactNativeRoot}/build",
"NODE_MODULES_DIR=$rootDir/../node_modules"
cFlags "-Wall", "-Werror", "-fexceptions", "-frtti", "-DWITH_INSPECTOR=1"
cppFlags "-std=c++17"
// Make sure this target name is the same you specify inside the
Expand Down Expand Up @@ -291,8 +293,10 @@ dependencies {
implementation "com.facebook.react:react-native:+" // From node_modules

if (enableHermes) {
debugImplementation files(new File(["node", "--print", "require.resolve('hermes-engine/package.json')"].execute(null, rootDir).text.trim(), "../android/hermes-debug.aar"))
releaseImplementation files(new File(["node", "--print", "require.resolve('hermes-engine/package.json')"].execute(null, rootDir).text.trim(), "../android/hermes-release.aar"))
//noinspection GradleDynamicVersion
implementation("com.facebook.react:hermes-engine:+") { // From node_modules
exclude group:'com.facebook.fbjni'
}
} else {
implementation jscFlavor
}
Expand Down Expand Up @@ -324,7 +328,11 @@ if (isNewArchitectureEnabled()) {
configurations.all {
resolutionStrategy.dependencySubstitution {
substitute(module("com.facebook.react:react-native"))
.using(project(":ReactAndroid")).because("On New Architecture we're building React Native from source")
.using(project(":ReactAndroid"))
.because("On New Architecture we're building React Native from source")
substitute(module("com.facebook.react:hermes-engine"))
.using(project(":ReactAndroid:hermes-engine"))
.because("On New Architecture we're building Hermes from source")
}
}
}
Expand Down
Expand Up @@ -7,6 +7,7 @@

import com.facebook.react.ReactActivity;
import com.facebook.react.ReactActivityDelegate;
import com.facebook.react.ReactRootView;

import expo.modules.ReactActivityDelegateWrapper;

Expand All @@ -28,29 +29,54 @@ protected void onCreate(Bundle savedInstanceState) {
super.onCreate(null);
}

/**
* Returns the instance of the {@link ReactActivityDelegate}. There the RootView is created and
* you can specify the renderer you wish to use - the new renderer (Fabric) or the old renderer
* (Paper).
*/
@Override
protected ReactActivityDelegate createReactActivityDelegate() {
ReactActivityDelegate delegate = new ReactActivityDelegateWrapper(this, BuildConfig.IS_NEW_ARCHITECTURE_ENABLED,
new ReactActivityDelegate(this, getMainComponentName()) {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

// Hacky way to prevent onboarding DevMenuActivity breaks detox testing,
// we do this by setting the dev-menu internal setting.
final Intent intent = getIntent();
final String action = intent.getAction();
final Uri initialUri = intent.getData();
if (action.equals(Intent.ACTION_VIEW) &&
initialUri != null &&
initialUri.getHost().equals("test-suite")) {
final String devMenuPrefKey = "expo.modules.devmenu.sharedpreferences";
final SharedPreferences pref = getApplicationContext().getSharedPreferences(devMenuPrefKey, MODE_PRIVATE);
pref.edit().putBoolean("isOnboardingFinished", true).apply();
}
return new ReactActivityDelegateWrapper(this, BuildConfig.IS_NEW_ARCHITECTURE_ENABLED,
new MainActivityDelegate(this, getMainComponentName())
);
}

public class MainActivityDelegate extends ReactActivityDelegate {
public MainActivityDelegate(ReactActivity activity, String mainComponentName) {
super(activity, mainComponentName);
}

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

// Hacky way to prevent onboarding DevMenuActivity breaks detox testing,
// we do this by setting the dev-menu internal setting.
final Intent intent = getIntent();
final String action = intent.getAction();
final Uri initialUri = intent.getData();
if (action.equals(Intent.ACTION_VIEW) &&
initialUri != null &&
initialUri.getHost().equals("test-suite")) {
final String devMenuPrefKey = "expo.modules.devmenu.sharedpreferences";
final SharedPreferences pref = getApplicationContext().getSharedPreferences(devMenuPrefKey, MODE_PRIVATE);
pref.edit().putBoolean("isOnboardingFinished", true).apply();
}
});
}

@Override
protected ReactRootView createRootView() {
ReactRootView reactRootView = new ReactRootView(getContext());
// If you opted-in for the New Architecture, we enable the Fabric Renderer.
reactRootView.setIsFabric(BuildConfig.IS_NEW_ARCHITECTURE_ENABLED);
return reactRootView;
}

return delegate;
@Override
protected boolean isConcurrentRootEnabled() {
// If you opted-in for the New Architecture, we enable Concurrent Root (i.e. React 18).
// More on this on https://reactjs.org/blog/2022/03/29/react-v18.html
return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
}
}
}
Expand Up @@ -10,7 +10,6 @@
import com.facebook.react.bridge.JSIModulePackage;
import com.facebook.react.config.ReactFeatureFlags;
import com.facebook.soloader.SoLoader;
import com.swmansion.reanimated.ReanimatedJSIModulePackage;

import java.util.List;

Expand All @@ -20,6 +19,7 @@
import expo.modules.ReactNativeHostWrapper;
import expo.modules.ApplicationLifecycleDispatcher;
import expo.modules.devlauncher.DevLauncherPackageDelegate;
import expo.modules.devmenu.DevMenuPackageDelegate;

public class MainApplication extends Application implements ReactApplication {
static final boolean USE_DEV_CLIENT = false;
Expand Down Expand Up @@ -64,6 +64,7 @@ public void onCreate() {
ReactNativeFlipper.initializeFlipper(this);
if (!USE_DEV_CLIENT) {
DevLauncherPackageDelegate.enableAutoSetup = false;
DevMenuPackageDelegate.enableAutoSetup = false;
}
ApplicationLifecycleDispatcher.onApplicationCreate(this);
}
Expand Down
Expand Up @@ -18,6 +18,7 @@
import com.facebook.react.fabric.CoreComponentsRegistry;
import com.facebook.react.fabric.EmptyReactNativeConfig;
import com.facebook.react.fabric.FabricJSIModuleProvider;
import com.facebook.react.fabric.ReactNativeConfig;
import com.facebook.react.uimanager.ViewManagerRegistry;
import dev.expo.payments.BuildConfig;
import dev.expo.payments.newarchitecture.components.MainComponentsRegistry;
Expand Down Expand Up @@ -105,7 +106,7 @@ public JSIModuleProvider<UIManager> getJSIModuleProvider() {
return new FabricJSIModuleProvider(
reactApplicationContext,
componentFactory,
new EmptyReactNativeConfig(),
ReactNativeConfig.DEFAULT_CONFIG,
viewManagerRegistry);
}
});
Expand Down
5 changes: 2 additions & 3 deletions apps/bare-expo/android/app/src/main/jni/Android.mk
Expand Up @@ -17,7 +17,7 @@ LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/*.cpp)
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)

# If you wish to add a custom TurboModule or Fabric component in your app you
# will have to uncomment those lines to include the generated source
# will have to uncomment those lines to include the generated source
# files from the codegen (placed in $(GENERATED_SRC_DIR)/codegen/jni)
#
# LOCAL_C_INCLUDES += $(GENERATED_SRC_DIR)/codegen/jni
Expand All @@ -28,8 +28,7 @@ LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
LOCAL_SHARED_LIBRARIES := \
libfabricjni \
libfbjni \
libfolly_futures \
libfolly_json \
libfolly_runtime \
libglog \
libjsi \
libreact_codegen_rncore \
Expand Down
6 changes: 2 additions & 4 deletions apps/bare-expo/android/build.gradle
Expand Up @@ -6,16 +6,14 @@ import org.apache.tools.ant.taskdefs.condition.Os
buildscript {
ext {
buildToolsVersion = "31.0.0"
gradlePluginVersion = '7.0.4'
gradlePluginVersion = '7.1.1'
minSdkVersion = 21
compileSdkVersion = 31
targetSdkVersion = 31
// Some dependencies still expect supportLibVersion to be defined
supportLibVersion = "29.0.0"
kotlinVersion = '1.6.10'
// for expo-dev-client
// TODO: remove once bare-expo has been upgraded to SDK 45 on main
expoPackageVersion = "45.0.0"
expoUpdatesVersion = null

if (System.properties['os.arch'] == "aarch64") {
Expand Down Expand Up @@ -45,7 +43,7 @@ buildscript {
// in the individual module build.gradle files
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"

classpath("de.undercouch:gradle-download-task:4.1.2")
classpath("de.undercouch:gradle-download-task:5.0.1")
}
}

Expand Down
5 changes: 2 additions & 3 deletions apps/bare-expo/android/settings.gradle
Expand Up @@ -4,9 +4,6 @@ applyNativeModulesSettingsGradle(settings)
include(":expo-modules-test-core")
project(":expo-modules-test-core").projectDir = new File("../../../packages/expo-modules-test-core/android")

include(":expo-dev-client")
project(":expo-dev-client").projectDir = new File("../../../packages/expo-dev-client/android")

// Include Expo modules
apply from: new File(["node", "--print", "require.resolve('expo/package.json')"].execute(null, rootDir).text.trim(), "../scripts/autolinking.gradle");
useExpoModules()
Expand All @@ -19,6 +16,8 @@ includeBuild(new File(["node", "--print", "require.resolve('react-native-gradle-
if (settings.hasProperty("newArchEnabled") && settings.newArchEnabled == "true") {
include(":ReactAndroid")
project(":ReactAndroid").projectDir = new File(["node", "--print", "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim(), "../ReactAndroid");
include(":ReactAndroid:hermes-engine")
project(":ReactAndroid:hermes-engine").projectDir = new File(["node", "--print", "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim(), "../ReactAndroid/hermes-engine");
}

include ':detox'
Expand Down
11 changes: 11 additions & 0 deletions apps/bare-expo/ios/.xcode.env
@@ -0,0 +1,11 @@
# This `.xcode.env` file is versioned and is used to source the environment
# used when running script phases inside Xcode.
# To customize your local environment, you can create an `.xcode.env.local`
# file that is not versioned.

# NODE_BINARY variable contains the PATH to the node executable.
#
# Customize the NODE_BINARY variable here.
# For example, to use nvm with brew, add the following line
# . "$(brew --prefix nvm)/nvm.sh" --no-use
export NODE_BINARY=$(command -v node)
2 changes: 2 additions & 0 deletions apps/bare-expo/ios/BareExpo.xcodeproj/project.pbxproj

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

27 changes: 25 additions & 2 deletions apps/bare-expo/ios/BareExpo/AppDelegate.mm
Expand Up @@ -27,6 +27,8 @@

#import <react/config/ReactNativeConfig.h>

static NSString *const kRNConcurrentRoot = @"concurrentRoot";

@interface AppDelegate () <RCTCxxBridgeDelegate, RCTTurboModuleManagerDelegate> {
RCTTurboModuleManager *_turboModuleManager;
RCTSurfacePresenterBridgeAdapter *_bridgeAdapter;
Expand All @@ -43,7 +45,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(
RCTAppSetupPrepareApp(application);

#if DEBUG
BOOL useDevClient = YES;
BOOL useDevClient = NO;

if (!useDevClient) {
ExpoDevLauncherReactDelegateHandler.enableAutoSetup = NO;
Expand All @@ -60,7 +62,8 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(
bridge.surfacePresenter = _bridgeAdapter.surfacePresenter;
#endif

UIView *rootView = [self.reactDelegate createRootViewWithBridge:bridge moduleName:@"main" initialProperties:nil];
NSDictionary *initProps = [self prepareInitialProps];
UIView *rootView = [self.reactDelegate createRootViewWithBridge:bridge moduleName:@"main" initialProperties:initProps];
rootView.backgroundColor = [UIColor whiteColor];
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIViewController *rootViewController = [self.reactDelegate createRootViewController];
Expand All @@ -79,6 +82,26 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(
return @[];
}

/// This method controls whether the `concurrentRoot`feature of React18 is turned on or off.
///
/// @see: https://reactjs.org/blog/2022/03/29/react-v18.html
/// @note: This requires to be rendering on Fabric (i.e. on the New Architecture).
/// @return: `true` if the `concurrentRoot` feture is enabled. Otherwise, it returns `false`.
- (BOOL)concurrentRootEnabled
{
// Switch this bool to turn on and off the concurrent root
return true;
}

- (NSDictionary *)prepareInitialProps
{
NSMutableDictionary *initProps = [NSMutableDictionary new];
#if RCT_NEW_ARCH_ENABLED
initProps[kRNConcurrentRoot] = @([self concurrentRootEnabled]);
#endif
return initProps;
}

- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
#ifdef DEBUG
Expand Down
2 changes: 1 addition & 1 deletion apps/bare-expo/ios/Podfile
Expand Up @@ -3,7 +3,7 @@ install! 'cocoapods',
:incremental_installation => true,
:deterministic_uuids => false
source 'https://cdn.cocoapods.org/'
platform :ios, '12.0'
platform :ios, '12.4'
inhibit_all_warnings!

# Import the auto-linking packages
Expand Down

0 comments on commit dec397f

Please sign in to comment.