From a745fa7e280fb863667d250ffb8d9d37e43c35e3 Mon Sep 17 00:00:00 2001 From: Tommy Nguyen <4123478+tido64@users.noreply.github.com> Date: Tue, 19 Aug 2025 15:03:06 +0200 Subject: [PATCH] feat: drop support for 0.75 and older BREAKING CHANGE: Dropped support for 0.75 and older --- CONTRIBUTING.md | 8 +- android/app/build.gradle | 155 +++------------- .../react/DevServerHelperCompat.kt | 15 -- .../react/DevServerHelperCompat.kt | 13 -- .../react/DevServerHelperCompat.kt | 16 -- android/app/src/main/jni/AutolinkingCompat.h | 12 -- android/app/src/main/jni/CMakeLists.txt | 2 - .../app/src/main/jni/ComponentsRegistry.cpp | 9 +- android/app/src/main/jni/ComponentsRegistry.h | 4 - android/app/src/main/jni/OnLoad.cpp | 2 - .../compat/ReactNativeHostCompat.kt | 29 --- .../reacttestapp/fabric/ComponentsRegistry.kt | 34 ---- .../turbomodule/TurboModuleManagerDelegate.kt | 37 ---- .../component/ComponentActivityDelegate.kt | 27 --- .../component/ComponentActivityDelegate.kt | 23 --- .../component/ComponentActivityDelegate.kt | 21 --- .../com/microsoft/reacttestapp/TestApp.kt | 68 ------- .../com/microsoft/reacttestapp/TestApp.kt | 62 ------- .../reacttetapp/react/MainReactNativeHost.kt | 172 ------------------ android/dependencies.gradle | 58 +----- android/gradle-wrapper.js | 5 - android/gradle.properties | 4 +- android/react-native.gradle | 37 +--- common/AppRegistry.cpp | 28 +-- example/android/build.gradle | 20 -- example/android/gradle.properties | 2 +- example/babel.config.js | 8 +- example/src/App.tsx | 7 +- example/src/core.ts | 15 +- ios/ReactTestApp/React+Compatibility.m | 52 ------ ios/app.mjs | 33 +--- ios/features.mjs | 34 +--- ios/pod_helpers.rb | 10 +- ios/test_app.rb | 23 +-- ios/use_react_native-0.70.rb | 29 --- ios/xcode.mjs | 14 +- package.json | 12 +- plugins/reanimated.js | 49 +---- scripts/configure-projects.js | 55 +----- scripts/configure.mjs | 57 ++---- scripts/init.mjs | 20 +- scripts/internal/set-react-version.mts | 118 +++--------- scripts/template.mjs | 36 +--- scripts/types.ts | 1 - test-app.gradle | 36 +--- test/android/gradle-wrapper.test.ts | 19 -- test/configure-projects.test.ts | 72 +++----- test/configure/gatherConfig.test.ts | 71 ++------ test/configure/getConfig.test.ts | 4 +- test/configure/getPlatformPackage.test.ts | 6 +- test/ios/app.test.ts | 18 -- test/ios/features.test.ts | 31 +--- test/ios/xcode.test.ts | 28 +-- test/pack.test.ts | 13 -- test/test_test_app.rb | 1 - windows/ExperimentalFeatures.props | 2 +- windows/app.mjs | 9 +- windows/project.mjs | 8 +- yarn.lock | 10 +- 59 files changed, 210 insertions(+), 1554 deletions(-) delete mode 100644 android/app/src/devserverhelper-0.73/java/com/microsoft/reacttestapp/react/DevServerHelperCompat.kt delete mode 100644 android/app/src/devserverhelper-0.74/java/com/microsoft/reacttestapp/react/DevServerHelperCompat.kt delete mode 100644 android/app/src/devserverhelper-pre-0.73/java/com/microsoft/reacttestapp/react/DevServerHelperCompat.kt delete mode 100644 android/app/src/new-arch/java/com/microsoft/reacttestapp/compat/ReactNativeHostCompat.kt delete mode 100644 android/app/src/new-arch/java/com/microsoft/reacttestapp/fabric/ComponentsRegistry.kt delete mode 100644 android/app/src/new-arch/java/com/microsoft/reacttestapp/turbomodule/TurboModuleManagerDelegate.kt delete mode 100644 android/app/src/reactactivitydelegate-0.72/java/com/microsoft/reacttestapp/component/ComponentActivityDelegate.kt delete mode 100644 android/app/src/reactactivitydelegate-0.74/java/com/microsoft/reacttestapp/component/ComponentActivityDelegate.kt delete mode 100644 android/app/src/reactactivitydelegate-pre-0.72/java/com/microsoft/reacttestapp/component/ComponentActivityDelegate.kt delete mode 100644 android/app/src/reactapplication-0.73/java/com/microsoft/reacttestapp/TestApp.kt delete mode 100644 android/app/src/reactapplication-pre-0.73/java/com/microsoft/reacttestapp/TestApp.kt delete mode 100644 android/app/src/reacthost-legacy/java/com/microsoft/reacttetapp/react/MainReactNativeHost.kt delete mode 100644 ios/use_react_native-0.70.rb diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 412386d7b..30e7affe0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -189,10 +189,10 @@ node --test test/pack.test.mjs ## Testing Specific React Native Versions `react-native-test-app` supports multiple versions of React Native. Use -`set-react-version` to set the version, e.g. to use 0.73: +`set-react-version` to set the version, e.g. to use 0.80: ```sh -npm run set-react-version 0.73 +npm run set-react-version 0.80 ``` This will modify both `package.json` and `example/package.json` to use packages @@ -218,11 +218,11 @@ update the title and fill out all the required fields. You can find the relevant discussion link at [`react-native-releases`][]. Use the [`test:matrix`][] script to both test and capture screenshots. We'll -need the screenshots for the PR we'll create later. For instance, to test 0.73, +need the screenshots for the PR we'll create later. For instance, to test 0.80, run: ```sh -npm run test:matrix 0.73 +npm run test:matrix 0.80 ``` At the minimum, we should be testing the lowest supported version (0.66 at the diff --git a/android/app/build.gradle b/android/app/build.gradle index 14b9142aa..63d06658c 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -17,25 +17,19 @@ buildDir = "${rootDir}/${name}/build" def reactNativePath = file(findNodeModulesPath("react-native", rootDir)) -if (autodetectReactNativeVersion || enableNewArchitecture) { - apply(plugin: "com.facebook.react") - - react { - reactNativeDir = reactNativePath - codegenDir = file( - reactNativeVersion >= v(0, 72, 0) - ? findNodeModulesPath("@react-native/codegen", reactNativePath) - : findNodeModulesPath("react-native-codegen", reactNativePath) - ) - } +apply(plugin: "com.facebook.react") - // We don't want the React plugin to bundle. - tasks.whenTaskAdded { task -> - // The task name can be found in `react-native-gradle-plugin`: - // https://github.com/facebook/react-native/blob/0.71-stable/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/TaskConfiguration.kt#L54 - if (task.name.startsWith("createBundle") && task.name.endsWith("JsAndAssets")) { - task.enabled = false - } +react { + reactNativeDir = reactNativePath + codegenDir = file(findNodeModulesPath("@react-native/codegen", reactNativePath)) +} + +// We don't want the React plugin to bundle. +tasks.whenTaskAdded { task -> + // The task name can be found in `react-native-gradle-plugin`: + // https://github.com/facebook/react-native/blob/0.71-stable/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/TaskConfiguration.kt#L54 + if (task.name.startsWith("createBundle") && task.name.endsWith("JsAndAssets")) { + task.enabled = false } } @@ -78,10 +72,8 @@ android { ndkVersion = project.ext.ndkVersion } - if (usePrefabs) { - buildFeatures { - prefab = true - } + buildFeatures { + prefab = true } kotlinOptions { @@ -107,14 +99,12 @@ android { resValue("string", "app_name", project.ext.react.appName) - def cppStd = reactNativeVersion >= v(0, 74, 0) ? "-std=c++20" : "-std=c++17" + def cppStd = "-std=c++20" if (enableNewArchitecture) { externalNativeBuild { cmake { arguments("-DANDROID_STL=c++_shared", - "-DNODE_MODULES_DIR=${reactNativePath}/..", "-DPROJECT_BUILD_DIR=${buildDir}", - "-DREACT_ANDROID_BUILD_DIR=${reactNativePath}/ReactAndroid/build", "-DREACT_ANDROID_DIR=${reactNativePath}/ReactAndroid") cppFlags(cppStd, "-frtti", "-fexceptions", "-DWITH_INSPECTOR=1") } @@ -142,28 +132,6 @@ android { } } - if (!enableNewArchitecture && !usePrefabs) { - def version = getPackageVersion("react-native", rootDir) - def allAar = file("${reactNativePath}/android/com/facebook/react/react-native/${version}/react-native-${version}.aar") - - def prepareDebugJSI = tasks.register("prepareDebugJSI", Copy) { - def debugAar = file("${reactNativePath}/android/com/facebook/react/react-native/${version}/react-native-${version}-debug.aar") - from(zipTree(debugAar.exists() ? debugAar : allAar).matching({ it.include "**/libjsi.so" })) - into("${buildDir}/outputs/jniLibs/debug") - } - - def prepareReleaseJSI = tasks.register("prepareReleaseJSI", Copy) { - def releaseAar = file("${reactNativePath}/android/com/facebook/react/react-native/${version}/react-native-${version}-release.aar") - from(zipTree(releaseAar.exists() ? releaseAar : allAar).matching({ it.include "**/libjsi.so" })) - into("${buildDir}/outputs/jniLibs/release") - } - - afterEvaluate { - preDebugBuild.dependsOn(prepareDebugJSI) - preReleaseBuild.dependsOn(prepareReleaseJSI) - } - } - lintOptions { lintConfig = file("lint.xml") } @@ -198,52 +166,12 @@ android { ? "src/old-arch/java" : reactNativeVersion >= v(0, 81, 0) ? "src/new-arch-0.81/java" - : reactNativeVersion >= v(0, 73, 0) - ? "src/new-arch-0.73/java" - : "src/new-arch/java", - - // TODO: Remove this block when we drop support for 0.74 - // https://github.com/facebook/react-native/commit/3283202248a36dbda553745afc46a3e3e2ab41a6 - reactNativeVersion >= v(0, 75, 0) - ? "src/reactactivitydelegate-0.75/java" - // TODO: Remove this block when we drop support for 0.73 - : reactNativeVersion >= v(0, 74, 0) - ? "src/reactactivitydelegate-0.74/java" - // TODO: Remove this block when we drop support for 0.71 - // https://github.com/facebook/react-native/commit/e5dd9cdc6688e63e75a7e0bebf380be1a9a5fe2b - : reactNativeVersion >= v(0, 72, 0) - ? "src/reactactivitydelegate-0.72/java" - : "src/reactactivitydelegate-pre-0.72/java", - - // TODO: Remove this block when we drop support for 0.74 - // https://github.com/facebook/react-native/commit/a1e81185416a53c7c7d0cfc67e40079fd0073e7c - reactNativeVersion >= v(0, 75, 0) - ? "src/devserverhelper-0.75/java" - // TODO: Remove this block when we drop support for 0.73 - // https://github.com/facebook/react-native/commit/cfa02eec50469059542ccbacbc51643b525ad461 - : reactNativeVersion >= v(0, 74, 0) - ? "src/devserverhelper-0.74/java" - // TODO: Remove this block when we drop support for 0.72 - // https://github.com/facebook/react-native/commit/da358d0ec7a492edb804b9cdce70e7516ee518ae - : reactNativeVersion >= v(0, 73, 0) - ? "src/devserverhelper-0.73/java" - : "src/devserverhelper-pre-0.73/java", - - // TODO: Remove this block when we drop support for 0.75 - // https://github.com/react-native-community/template/commit/f738a366b194dd21d4d2bc14c9215b630714dd70 - reactNativeVersion >= v(0, 76, 0) - ? "src/reactapplication-0.76/java" - // TODO: Remove this block when we drop support for 0.72 - // https://github.com/facebook/react-native/commit/c3f672cef7d4f287d3d729d33650f917ed132a0c - : reactNativeVersion < v(0, 73, 0) - ? "src/reactapplication-pre-0.73/java" - : "src/reactapplication-0.73/java", - - // TODO: Remove this block when we drop support for 0.75 - // https://github.com/react-native-community/template/commit/f738a366b194dd21d4d2bc14c9215b630714dd70 - reactNativeVersion >= v(0, 76, 0) - ? "src/reacthost-0.76/java" - : "src/reacthost-legacy/java", + : "src/new-arch-0.73/java", + + "src/devserverhelper-0.75/java", + "src/reactactivitydelegate-0.75/java", + "src/reactapplication-0.76/java", + "src/reacthost-0.76/java", ] } @@ -260,22 +188,8 @@ android { dependencies { implementation project(":support") - if (project.ext.react.enableHermes) { - if (autodetectReactNativeVersion) { - implementation("com.facebook.react:hermes-android") - } else { - implementation("com.facebook.react:hermes-engine:+") { - exclude(group: "com.facebook.fbjni") - } - } - } - - if (autodetectReactNativeVersion) { - implementation("com.facebook.react:react-android") - } else { - def version = getPackageVersion("react-native", rootDir) - implementation("com.facebook.react:react-native:${version}") - } + implementation("com.facebook.react:hermes-android") + implementation("com.facebook.react:react-android") implementation(libraries.androidAppCompat) implementation(libraries.androidCoreKotlinExtensions) @@ -288,25 +202,10 @@ dependencies { implementation(libraries.mlKitBarcodeScanning) } - if (reactNativeVersion == 0 || reactNativeVersion >= v(0, 75, 0)) { - // https://github.com/facebook/react-native/blob/b0c0bb45911434ea654ba7e2feff4686061eba7a/packages/react-native-gradle-plugin/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/ReactExtension.kt#L162 - def dependencies = autolinkingInfo(buildDir) - dependencies.each { path, info -> - info.configurations.each { configuration -> - add(configuration, project(path)) - } - } - } -} - -if (!enableNewArchitecture && !usePrefabs) { - configurations.all { - resolutionStrategy { - // Force version here otherwise Gradle will pick up a newer version: - // https://github.com/facebook/react-native/issues/35210 - def version = getPackageVersion("react-native", rootDir) - force("com.facebook.react:react-native:${version}") - force("com.facebook.react:hermes-engine:${version}") + // https://github.com/facebook/react-native/blob/b0c0bb45911434ea654ba7e2feff4686061eba7a/packages/react-native-gradle-plugin/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/ReactExtension.kt#L162 + autolinkingInfo(buildDir).each { path, info -> + info.configurations.each { configuration -> + add(configuration, project(path)) } } } diff --git a/android/app/src/devserverhelper-0.73/java/com/microsoft/reacttestapp/react/DevServerHelperCompat.kt b/android/app/src/devserverhelper-0.73/java/com/microsoft/reacttestapp/react/DevServerHelperCompat.kt deleted file mode 100644 index 73038e639..000000000 --- a/android/app/src/devserverhelper-0.73/java/com/microsoft/reacttestapp/react/DevServerHelperCompat.kt +++ /dev/null @@ -1,15 +0,0 @@ -package com.microsoft.reacttestapp.react - -import android.content.Context -import com.facebook.react.devsupport.DevServerHelper -import com.facebook.react.devsupport.InspectorPackagerConnection.BundleStatus -import com.facebook.react.modules.debug.interfaces.DeveloperSettings -import com.facebook.react.packagerconnection.PackagerConnectionSettings - -fun createDevServerHelper(context: Context, developerSettings: DeveloperSettings): DevServerHelper = - DevServerHelper( - developerSettings, - context.packageName, - { BundleStatus() }, - PackagerConnectionSettings(context) - ) diff --git a/android/app/src/devserverhelper-0.74/java/com/microsoft/reacttestapp/react/DevServerHelperCompat.kt b/android/app/src/devserverhelper-0.74/java/com/microsoft/reacttestapp/react/DevServerHelperCompat.kt deleted file mode 100644 index 05c8d1b5f..000000000 --- a/android/app/src/devserverhelper-0.74/java/com/microsoft/reacttestapp/react/DevServerHelperCompat.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.microsoft.reacttestapp.react - -import android.content.Context -import com.facebook.react.devsupport.DevServerHelper -import com.facebook.react.modules.debug.interfaces.DeveloperSettings -import com.facebook.react.packagerconnection.PackagerConnectionSettings - -fun createDevServerHelper(context: Context, developerSettings: DeveloperSettings): DevServerHelper = - DevServerHelper( - developerSettings, - context.packageName, - PackagerConnectionSettings(context) - ) diff --git a/android/app/src/devserverhelper-pre-0.73/java/com/microsoft/reacttestapp/react/DevServerHelperCompat.kt b/android/app/src/devserverhelper-pre-0.73/java/com/microsoft/reacttestapp/react/DevServerHelperCompat.kt deleted file mode 100644 index d02d1dda5..000000000 --- a/android/app/src/devserverhelper-pre-0.73/java/com/microsoft/reacttestapp/react/DevServerHelperCompat.kt +++ /dev/null @@ -1,16 +0,0 @@ -package com.microsoft.reacttestapp.react - -import android.content.Context -import com.facebook.react.devsupport.DevInternalSettings -import com.facebook.react.devsupport.DevServerHelper -import com.facebook.react.devsupport.InspectorPackagerConnection.BundleStatus -import com.facebook.react.modules.debug.interfaces.DeveloperSettings - -fun createDevServerHelper( - context: Context, - @Suppress("UNUSED_PARAMETER") developerSettings: DeveloperSettings -): DevServerHelper = DevServerHelper( - DevInternalSettings(context) {}, - context.packageName, - { BundleStatus() } -) diff --git a/android/app/src/main/jni/AutolinkingCompat.h b/android/app/src/main/jni/AutolinkingCompat.h index 608abf7a4..1cede2240 100644 --- a/android/app/src/main/jni/AutolinkingCompat.h +++ b/android/app/src/main/jni/AutolinkingCompat.h @@ -13,22 +13,10 @@ #endif // __has_include() // >= 0.81 -#if __has_include() // >= 0.75 - #include #define autolinking_ModuleProvider facebook::react::autolinking_ModuleProvider #define autolinking_cxxModuleProvider facebook::react::autolinking_cxxModuleProvider #define autolinking_registerProviders facebook::react::autolinking_registerProviders -#else // < 0.75 - -#include - -#define autolinking_ModuleProvider facebook::react::rncli_ModuleProvider -#define autolinking_cxxModuleProvider facebook::react::rncli_cxxModuleProvider -#define autolinking_registerProviders facebook::react::rncli_registerProviders - -#endif // __has_include() - #endif // REACTAPP_JNI_AUTOLINKINGCOMPAT_H_ diff --git a/android/app/src/main/jni/CMakeLists.txt b/android/app/src/main/jni/CMakeLists.txt index 050d06b5e..7f358b3d4 100644 --- a/android/app/src/main/jni/CMakeLists.txt +++ b/android/app/src/main/jni/CMakeLists.txt @@ -12,8 +12,6 @@ set(REACTTESTAPP_SOURCE_FILES # Suppress 'Manually-specified variables were not used by the project' warning set(UNUSED_VARIABLES - ${NODE_MODULES_DIR} # TODO: No longer used in 0.72 - ${REACT_ANDROID_BUILD_DIR} # TODO: No longer used in 0.72 ${REACT_COMMON_DIR} ${REACT_JNILIBS_DIR} ) diff --git a/android/app/src/main/jni/ComponentsRegistry.cpp b/android/app/src/main/jni/ComponentsRegistry.cpp index 83fa11687..8d42b14f9 100644 --- a/android/app/src/main/jni/ComponentsRegistry.cpp +++ b/android/app/src/main/jni/ComponentsRegistry.cpp @@ -2,16 +2,13 @@ #if !__has_include() +// clang-format off #include "AutolinkingCompat.h" - -#if __has_include() // >= 0.71 -#include -#else // < 0.71 -#include -#endif // __has_include() +// clang-format on #include +#include #include #include #include diff --git a/android/app/src/main/jni/ComponentsRegistry.h b/android/app/src/main/jni/ComponentsRegistry.h index a694be1ce..c82c80ded 100644 --- a/android/app/src/main/jni/ComponentsRegistry.h +++ b/android/app/src/main/jni/ComponentsRegistry.h @@ -3,11 +3,7 @@ #include -#if __has_include() // >= 0.71 #include -#else // < 0.71 -#include -#endif namespace ReactTestApp { diff --git a/android/app/src/main/jni/OnLoad.cpp b/android/app/src/main/jni/OnLoad.cpp index 31201b7ad..fc1717a7e 100644 --- a/android/app/src/main/jni/OnLoad.cpp +++ b/android/app/src/main/jni/OnLoad.cpp @@ -31,12 +31,10 @@ namespace std::shared_ptr javaModuleProvider(const std::string &name, const JavaTurboModule::InitParams ¶ms) { -#if __has_include() // >= 0.75 // We first try to look up core modules if (auto module = rncore_ModuleProvider(name, params)) { return module; } -#endif // __has_include() // And we fallback to the module providers autolinked by RN CLI return autolinking_ModuleProvider(name, params); diff --git a/android/app/src/new-arch/java/com/microsoft/reacttestapp/compat/ReactNativeHostCompat.kt b/android/app/src/new-arch/java/com/microsoft/reacttestapp/compat/ReactNativeHostCompat.kt deleted file mode 100644 index 5de8f8d0d..000000000 --- a/android/app/src/new-arch/java/com/microsoft/reacttestapp/compat/ReactNativeHostCompat.kt +++ /dev/null @@ -1,29 +0,0 @@ -package com.microsoft.reacttestapp.compat - -import android.app.Application -import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint -import com.facebook.react.defaults.DefaultReactNativeHost -import com.facebook.soloader.SoLoader -import com.microsoft.reacttestapp.BuildConfig - -abstract class ReactNativeHostCompat(application: Application) : - DefaultReactNativeHost(application) { - - companion object { - init { - try { - DefaultNewArchitectureEntryPoint.load( - turboModulesEnabled = BuildConfig.REACTAPP_USE_FABRIC, - fabricEnabled = BuildConfig.REACTAPP_USE_FABRIC - ) - } catch (e: UnsatisfiedLinkError) { - // Older versions of `DefaultNewArchitectureEntryPoint` is - // hard coded to load `libappmodules.so` - } - SoLoader.loadLibrary("reacttestapp_appmodules") - } - } - - override val isNewArchEnabled: Boolean = BuildConfig.REACTAPP_USE_FABRIC - override val isHermesEnabled: Boolean? = true -} diff --git a/android/app/src/new-arch/java/com/microsoft/reacttestapp/fabric/ComponentsRegistry.kt b/android/app/src/new-arch/java/com/microsoft/reacttestapp/fabric/ComponentsRegistry.kt deleted file mode 100644 index e36c0d44a..000000000 --- a/android/app/src/new-arch/java/com/microsoft/reacttestapp/fabric/ComponentsRegistry.kt +++ /dev/null @@ -1,34 +0,0 @@ -package com.microsoft.reacttestapp.fabric - -import com.facebook.jni.HybridData -import com.facebook.proguard.annotations.DoNotStrip -import com.facebook.react.fabric.ComponentFactory -import com.facebook.soloader.SoLoader - -/** - * The corresponding C++ implementation is in `android/app/src/main/jni/ComponentsRegistry.cpp` - */ -@DoNotStrip -class ComponentsRegistry @DoNotStrip private constructor(componentFactory: ComponentFactory) { - - companion object { - @DoNotStrip - fun register(componentFactory: ComponentFactory): ComponentsRegistry = - ComponentsRegistry(componentFactory) - - init { - SoLoader.loadLibrary("fabricjni") - SoLoader.loadLibrary("reacttestapp_appmodules") - } - } - - @DoNotStrip - private val mHybridData: HybridData - - @DoNotStrip - private external fun initHybrid(componentFactory: ComponentFactory): HybridData - - init { - mHybridData = initHybrid(componentFactory) - } -} diff --git a/android/app/src/new-arch/java/com/microsoft/reacttestapp/turbomodule/TurboModuleManagerDelegate.kt b/android/app/src/new-arch/java/com/microsoft/reacttestapp/turbomodule/TurboModuleManagerDelegate.kt deleted file mode 100644 index 1f000981c..000000000 --- a/android/app/src/new-arch/java/com/microsoft/reacttestapp/turbomodule/TurboModuleManagerDelegate.kt +++ /dev/null @@ -1,37 +0,0 @@ -package com.microsoft.reacttestapp.turbomodule - -import com.facebook.jni.HybridData -import com.facebook.react.ReactPackage -import com.facebook.react.ReactPackageTurboModuleManagerDelegate -import com.facebook.react.bridge.ReactApplicationContext - -/** - * These type aliases are here to prevent `@react-native-community/cli` from - * marking them as native modules to autolink. - * - * See also `matchClassName` in - * https://github.com/react-native-community/cli/blob/8.x/packages/platform-android/src/config/findPackageClassName.ts#L25 - */ -typealias PackagesList = List -typealias ReactTurboModuleManagerDelegate = ReactPackageTurboModuleManagerDelegate -typealias ReactTurboModuleManagerDelegateBuilder = ReactPackageTurboModuleManagerDelegate.Builder - -/** - * The corresponding C++ implementation is in `android/app/src/main/jni/TurboModuleManagerDelegate.cpp` - */ -class TurboModuleManagerDelegate protected constructor( - reactApplicationContext: ReactApplicationContext?, - packages: PackagesList? -) : ReactTurboModuleManagerDelegate(reactApplicationContext, packages) { - - external override fun initHybrid(): HybridData - - external fun canCreateTurboModule(moduleName: String?): Boolean - - class Builder : ReactTurboModuleManagerDelegateBuilder() { - override fun build( - context: ReactApplicationContext?, - packages: PackagesList? - ): TurboModuleManagerDelegate = TurboModuleManagerDelegate(context, packages) - } -} diff --git a/android/app/src/reactactivitydelegate-0.72/java/com/microsoft/reacttestapp/component/ComponentActivityDelegate.kt b/android/app/src/reactactivitydelegate-0.72/java/com/microsoft/reacttestapp/component/ComponentActivityDelegate.kt deleted file mode 100644 index bc60daed1..000000000 --- a/android/app/src/reactactivitydelegate-0.72/java/com/microsoft/reacttestapp/component/ComponentActivityDelegate.kt +++ /dev/null @@ -1,27 +0,0 @@ -package com.microsoft.reacttestapp.component - -import android.os.Bundle -import com.facebook.react.ReactActivity -import com.facebook.react.ReactActivityDelegate -import com.facebook.react.ReactRootView -import com.microsoft.reacttestapp.BuildConfig - -class ComponentActivityDelegate(activity: ReactActivity, mainComponentName: String?) : - ReactActivityDelegate(activity, mainComponentName) { - - override fun getLaunchOptions(): Bundle? = plainActivity.intent.extras?.getBundle( - ComponentActivity.COMPONENT_INITIAL_PROPERTIES - ) - - override fun createRootView(): ReactRootView { - val rootView = super.createRootView() - rootView.setIsFabric(BuildConfig.REACTAPP_USE_FABRIC) - return rootView - } - - override fun createRootView(bundle: Bundle?): ReactRootView { - val rootView = super.createRootView(bundle) - rootView.setIsFabric(BuildConfig.REACTAPP_USE_FABRIC) - return rootView - } -} diff --git a/android/app/src/reactactivitydelegate-0.74/java/com/microsoft/reacttestapp/component/ComponentActivityDelegate.kt b/android/app/src/reactactivitydelegate-0.74/java/com/microsoft/reacttestapp/component/ComponentActivityDelegate.kt deleted file mode 100644 index fde3488a2..000000000 --- a/android/app/src/reactactivitydelegate-0.74/java/com/microsoft/reacttestapp/component/ComponentActivityDelegate.kt +++ /dev/null @@ -1,23 +0,0 @@ -package com.microsoft.reacttestapp.component - -import android.os.Bundle -import com.facebook.react.ReactActivity -import com.facebook.react.ReactActivityDelegate -import com.facebook.react.ReactRootView -import com.microsoft.reacttestapp.BuildConfig - -class ComponentActivityDelegate(activity: ReactActivity, mainComponentName: String?) : - ReactActivityDelegate(activity, mainComponentName) { - - override fun getLaunchOptions(): Bundle? = plainActivity.intent.extras?.getBundle( - ComponentActivity.COMPONENT_INITIAL_PROPERTIES - ) - - override fun isFabricEnabled(): Boolean = BuildConfig.REACTAPP_USE_FABRIC - - override fun createRootView(): ReactRootView = - ReactRootView(context).apply { setIsFabric(BuildConfig.REACTAPP_USE_FABRIC) } - - override fun createRootView(bundle: Bundle?): ReactRootView = - ReactRootView(context).apply { setIsFabric(BuildConfig.REACTAPP_USE_FABRIC) } -} diff --git a/android/app/src/reactactivitydelegate-pre-0.72/java/com/microsoft/reacttestapp/component/ComponentActivityDelegate.kt b/android/app/src/reactactivitydelegate-pre-0.72/java/com/microsoft/reacttestapp/component/ComponentActivityDelegate.kt deleted file mode 100644 index 40b65799a..000000000 --- a/android/app/src/reactactivitydelegate-pre-0.72/java/com/microsoft/reacttestapp/component/ComponentActivityDelegate.kt +++ /dev/null @@ -1,21 +0,0 @@ -package com.microsoft.reacttestapp.component - -import android.os.Bundle -import com.facebook.react.ReactActivity -import com.facebook.react.ReactActivityDelegate -import com.facebook.react.ReactRootView -import com.microsoft.reacttestapp.BuildConfig - -class ComponentActivityDelegate(activity: ReactActivity, mainComponentName: String?) : - ReactActivityDelegate(activity, mainComponentName) { - - override fun getLaunchOptions(): Bundle? = plainActivity.intent.extras?.getBundle( - ComponentActivity.COMPONENT_INITIAL_PROPERTIES - ) - - override fun createRootView(): ReactRootView { - val rootView = super.createRootView() - rootView.setIsFabric(BuildConfig.REACTAPP_USE_FABRIC) - return rootView - } -} diff --git a/android/app/src/reactapplication-0.73/java/com/microsoft/reacttestapp/TestApp.kt b/android/app/src/reactapplication-0.73/java/com/microsoft/reacttestapp/TestApp.kt deleted file mode 100644 index 768f155f6..000000000 --- a/android/app/src/reactapplication-0.73/java/com/microsoft/reacttestapp/TestApp.kt +++ /dev/null @@ -1,68 +0,0 @@ -package com.microsoft.reacttestapp - -import android.app.Activity -import android.app.Application -import android.content.Context -import com.facebook.react.PackageList -import com.facebook.react.ReactApplication -import com.facebook.react.ReactHost -import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost -import com.facebook.soloader.SoLoader -import com.microsoft.reacttestapp.manifest.Manifest -import com.microsoft.reacttestapp.manifest.ManifestProvider -import com.microsoft.reacttestapp.react.MainReactNativeHost -import com.microsoft.reacttestapp.react.ReactBundleNameProvider -import com.microsoft.reacttestapp.support.ReactTestAppLifecycleEvents - -class TestApp : - Application(), - ReactApplication { - - val bundleNameProvider: ReactBundleNameProvider - get() = reactNativeBundleNameProvider - - val manifest: Manifest by lazy { - ManifestProvider.manifest() - } - - override val reactHost: ReactHost - get() = getDefaultReactHost(this.applicationContext, reactNativeHost) - - override val reactNativeHost: MainReactNativeHost - get() = reactNativeHostInternal - - private lateinit var reactNativeBundleNameProvider: ReactBundleNameProvider - private lateinit var reactNativeHostInternal: MainReactNativeHost - - fun reloadJSFromServer(activity: Activity, bundleURL: String) { - reactNativeHostInternal.reloadJSFromServer(activity, bundleURL) - } - - override fun onCreate() { - super.onCreate() - - @Suppress("DEPRECATION") - SoLoader.init(this, false) - - reactNativeBundleNameProvider = ReactBundleNameProvider(this, manifest.bundleRoot) - reactNativeHostInternal = MainReactNativeHost(this, reactNativeBundleNameProvider) - - val eventConsumers = PackageList(this).packages - .filter { it is ReactTestAppLifecycleEvents } - .map { it as ReactTestAppLifecycleEvents } - - eventConsumers.forEach { it.onTestAppInitialized() } - - reactNativeHostInternal.init( - beforeReactNativeInit = { - eventConsumers.forEach { it.onTestAppWillInitializeReactNative() } - }, - afterReactNativeInit = { - eventConsumers.forEach { it.onTestAppDidInitializeReactNative() } - } - ) - } -} - -val Context.testApp: TestApp - get() = applicationContext as TestApp diff --git a/android/app/src/reactapplication-pre-0.73/java/com/microsoft/reacttestapp/TestApp.kt b/android/app/src/reactapplication-pre-0.73/java/com/microsoft/reacttestapp/TestApp.kt deleted file mode 100644 index be9e56932..000000000 --- a/android/app/src/reactapplication-pre-0.73/java/com/microsoft/reacttestapp/TestApp.kt +++ /dev/null @@ -1,62 +0,0 @@ -package com.microsoft.reacttestapp - -import android.app.Activity -import android.app.Application -import android.content.Context -import com.facebook.react.PackageList -import com.facebook.react.ReactApplication -import com.facebook.soloader.SoLoader -import com.microsoft.reacttestapp.manifest.Manifest -import com.microsoft.reacttestapp.manifest.ManifestProvider -import com.microsoft.reacttestapp.react.MainReactNativeHost -import com.microsoft.reacttestapp.react.ReactBundleNameProvider -import com.microsoft.reacttestapp.support.ReactTestAppLifecycleEvents - -class TestApp : - Application(), - ReactApplication { - - val bundleNameProvider: ReactBundleNameProvider - get() = reactNativeBundleNameProvider - - val manifest: Manifest by lazy { - ManifestProvider.manifest() - } - - private lateinit var reactNativeBundleNameProvider: ReactBundleNameProvider - private lateinit var reactNativeHostInternal: MainReactNativeHost - - fun reloadJSFromServer(activity: Activity, bundleURL: String) { - reactNativeHostInternal.reloadJSFromServer(activity, bundleURL) - } - - override fun onCreate() { - super.onCreate() - - @Suppress("DEPRECATION") - SoLoader.init(this, false) - - reactNativeBundleNameProvider = ReactBundleNameProvider(this, manifest.bundleRoot) - reactNativeHostInternal = MainReactNativeHost(this, reactNativeBundleNameProvider) - - val eventConsumers = PackageList(this).packages - .filter { it is ReactTestAppLifecycleEvents } - .map { it as ReactTestAppLifecycleEvents } - - eventConsumers.forEach { it.onTestAppInitialized() } - - reactNativeHostInternal.init( - beforeReactNativeInit = { - eventConsumers.forEach { it.onTestAppWillInitializeReactNative() } - }, - afterReactNativeInit = { - eventConsumers.forEach { it.onTestAppDidInitializeReactNative() } - } - ) - } - - override fun getReactNativeHost() = reactNativeHostInternal -} - -val Context.testApp: TestApp - get() = applicationContext as TestApp diff --git a/android/app/src/reacthost-legacy/java/com/microsoft/reacttetapp/react/MainReactNativeHost.kt b/android/app/src/reacthost-legacy/java/com/microsoft/reacttetapp/react/MainReactNativeHost.kt deleted file mode 100644 index c4e3003c0..000000000 --- a/android/app/src/reacthost-legacy/java/com/microsoft/reacttetapp/react/MainReactNativeHost.kt +++ /dev/null @@ -1,172 +0,0 @@ -package com.microsoft.reacttestapp.react - -import android.app.Activity -import android.app.Application -import android.content.Context -import android.content.Intent -import androidx.core.net.toUri -import com.facebook.hermes.reactexecutor.HermesExecutorFactory -import com.facebook.react.PackageList -import com.facebook.react.ReactInstanceEventListener -import com.facebook.react.ReactInstanceManager -import com.facebook.react.ReactPackage -import com.facebook.react.bridge.JavaScriptExecutorFactory -import com.facebook.react.bridge.ReactContext -import com.facebook.react.devsupport.interfaces.DevSupportManager -import com.facebook.react.packagerconnection.PackagerConnectionSettings -import com.microsoft.reacttestapp.BuildConfig -import com.microsoft.reacttestapp.MainActivity -import com.microsoft.reacttestapp.R -import java.util.Collections.synchronizedList -import java.util.concurrent.CountDownLatch - -@Suppress("TYPEALIAS_EXPANSION_DEPRECATION") -class MainReactNativeHost( - application: Application, - private val reactBundleNameProvider: ReactBundleNameProvider -) : com.microsoft.reacttestapp.compat.ReactNativeHostCompat(application) { - val jsExecutorName: String - get() = javaScriptExecutorFactory.toString() - - var source: BundleSource = - if (reactBundleNameProvider.bundleName == null || isPackagerRunning(application)) { - BundleSource.Server - } else { - BundleSource.Disk - } - - var onBundleSourceChanged: ((newSource: BundleSource) -> Unit)? = null - - private var currentActivityTracker = CurrentActivityTracker() - - private val reactInstanceEventListeners = - synchronizedList(arrayListOf()) - - fun init(beforeReactNativeInit: () -> Unit, afterReactNativeInit: () -> Unit) { - if (BuildConfig.DEBUG && hasInstance()) { - error("init() can only be called once on startup") - } - - application.registerActivityLifecycleCallbacks(currentActivityTracker) - - // When we reference `reactInstanceManager` below, `ReactNativeHost` will start creating a - // `ReactInstanceManager` instance. - beforeReactNativeInit() - - val reactInstanceListener = object : ReactInstanceEventListener { - override fun onReactContextInitialized(context: ReactContext) { - afterReactNativeInit() - - // proactively removing the listener to avoid leaking memory - // and to avoid dupe calls to afterReactNativeInit() - reactInstanceManager.removeReactInstanceEventListener(this) - } - } - - reactInstanceManager.addReactInstanceEventListener(reactInstanceListener) - } - - fun addReactInstanceEventListener(listener: ReactInstanceEventListener) { - reactInstanceEventListeners.add(listener) - reactInstanceManager.addReactInstanceEventListener(listener) - } - - fun reload(activity: Activity, newSource: BundleSource) { - val action = source.moveTo(newSource) - source = newSource - - when (action) { - BundleSource.Action.RELOAD -> { - reactInstanceManager.devSupportManager.handleReloadJS() - } - BundleSource.Action.RESTART -> { - if (activity !is MainActivity) { - activity.navigateUpTo(Intent(application, MainActivity.Companion::class.java)) - } - clear() - } - } - - onBundleSourceChanged?.invoke(newSource) - } - - fun reloadJSFromServer(activity: Activity, bundleURL: String) { - val uri = bundleURL.toUri() - PackagerConnectionSettings(activity).debugServerHost = - if (uri.port > 0) { - "${uri.host}:${uri.port}" - } else { - uri.host ?: "localhost" - } - reload(activity, BundleSource.Server) - } - - override fun createReactInstanceManager(): ReactInstanceManager { - val reactInstanceManager = super.createReactInstanceManager() - addCustomDevOptions(reactInstanceManager.devSupportManager) - - synchronized(reactInstanceEventListeners) { - val i = reactInstanceEventListeners.iterator() - while (i.hasNext()) { - reactInstanceManager.addReactInstanceEventListener(i.next()) - } - } - - return reactInstanceManager - } - - override fun getJavaScriptExecutorFactory(): JavaScriptExecutorFactory = HermesExecutorFactory() - - override fun getJSMainModuleName() = "index" - - // We may not always have (or need) a JS bundle, but - // `ReactNativeHost.createReactInstanceManager` asserts it so we need to - // return something. - override fun getBundleAssetName() = reactBundleNameProvider.bundleName ?: "main.android.bundle" - - override fun getUseDeveloperSupport() = source == BundleSource.Server - - override fun getPackages(): List = PackageList(application).packages - - private fun addCustomDevOptions(devSupportManager: DevSupportManager) { - val bundleOption = application.resources.getString( - if (source == BundleSource.Disk) { - R.string.load_from_dev_server - } else { - R.string.load_embedded_js_bundle - } - ) - devSupportManager.addCustomDevOption(bundleOption) { - currentActivityTracker.get()?.let { - when (source) { - BundleSource.Disk -> reload(it, BundleSource.Server) - BundleSource.Server -> reload(it, BundleSource.Disk) - } - } - } - } - - private fun isPackagerRunning(context: Context): Boolean { - if (!hasInstance()) { - // Return early otherwise we will get in an initialization loop. - // `source` may be initialized by calling this function. Without - // this check, the `getReactInstanceManager()` call below will - // instantiate `ReactInstanceManager`, which in turn will try to - // access `source`. - return BuildConfig.DEBUG - } - - val latch = CountDownLatch(1) - var packagerIsRunning = false - - reactInstanceManager.devSupportManager.devSettings?.let { devSettings -> - createDevServerHelper(context, devSettings).isPackagerRunning { - packagerIsRunning = it - latch.countDown() - } - } - - latch.await() - return packagerIsRunning - } -} diff --git a/android/dependencies.gradle b/android/dependencies.gradle index f637a8f3f..a39708acf 100644 --- a/android/dependencies.gradle +++ b/android/dependencies.gradle @@ -5,22 +5,6 @@ if (!hasProperty("rnta_react_native_gradle")) { apply(from: "${buildscript.sourceFile.getParent()}/react-native.gradle") } -/** - * Returns the recommended Gradle plugin version for the specified React Native - * version. - */ -def getDefaultGradlePluginVersion = { int reactNativeVersion -> - // Gradle plugin version can be found in the template: - // https://github.com/facebook/react-native/blob/main/packages/react-native/template/android/build.gradle - if (reactNativeVersion == 0 || reactNativeVersion >= v(0, 73, 0)) { - return "" - } else if (reactNativeVersion >= v(0, 71, 0)) { - return "7.3.1" - } else { - return "7.2.2" - } -} - def getDependencyVersionFromCatalog = { String versionCatalog, String dependency, String fallback -> if (versionCatalog == null) { return fallback @@ -63,32 +47,19 @@ ext { targetSdkVersion = rootProject.findProperty("react.targetSdkVersion") ?: getDependencyVersionNumberFromCatalog(versionCatalog, "targetSdk", 33) - autodetectReactNativeVersion = reactNativeVersion == 0 || reactNativeVersion >= v(0, 71, 0) enableNewArchitecture = isNewArchitectureEnabled(project) enableBridgeless = isBridgelessEnabled(project, enableNewArchitecture) - usePrefabs = reactNativeVersion == 0 || reactNativeVersion >= v(0, 71, 0) - androidPluginVersion = getDefaultGradlePluginVersion(reactNativeVersion) kotlinVersion = rootProject.findProperty("KOTLIN_VERSION") ?: getKotlinVersion(versionCatalog) // We need only set `ndkVersion` when building react-native from source. if (rootProject.hasProperty("ANDROID_NDK_VERSION")) { ndkVersion = rootProject.properties["ANDROID_NDK_VERSION"] - } else if (reactNativeVersion >= v(0, 74, 0)) { + } else { // https://github.com/facebook/react-native/commit/9ce7b564131c5b2075489c09ff05325ddc28014a ndkVersion = getDependencyVersionFromCatalog(versionCatalog, "ndkVersion", "26.1.10909125") - } else if (System.properties["os.arch"] == "aarch64" && androidPluginVersion == "7.2.2") { - // NDK r23c has been patched to support Apple M1 and is default in AGP - // 7.3.0. Prior to 0.71, we still need to set `ndkVersion` because we'll - // be using AGP 7.2.2 (see `androidPluginVersion` above). - // Note that even though newer 23.x versions exist, we'll stick to AGP's - // default. See also - // https://developer.android.com/build/releases/past-releases/agp-7-3-0-release-notes - ndkVersion = "23.1.7779620" } - def kotlinVersionNumber = toVersionNumber(kotlinVersion) - /** * Dependabot requires a `dependencies.gradle` to evaluate Java * dependencies. It is also very particular about the formatting and cannot @@ -109,33 +80,14 @@ ext { mlKitBarcodeScanning : "com.google.mlkit:barcode-scanning:17.3.0", ] - // Separate block so bots can parse this file properly - if (compileSdkVersion < 35) { - libraries.androidCoreKotlinExtensions = ["androidx.core", "core-ktx", "1.13.1"].join(":") - libraries.androidRecyclerView = ["androidx.recyclerview", "recyclerview", "1.3.2"].join(":") - } - if (kotlinVersionNumber < v(1, 8, 0)) { - libraries.androidAppCompat = ["androidx.appcompat", "appcompat", "1.6.1"].join(":") - libraries.androidCamera = ["androidx.camera", "camera-camera2", "1.2.0-beta02"].join(":") - libraries.androidCameraMlKitVision = ["androidx.camera", "camera-mlkit-vision", "1.2.0-beta02"].join(":") - libraries.androidCoreKotlinExtensions = ["androidx.core", "core-ktx", "1.9.0"].join(":") - } - getReactNativeDependencies = { // Hint: Use `./gradlew buildEnvironment` to check whether these are // correctly set. - def dependencies = [ - androidPluginVersion == "" - ? "com.android.tools.build:gradle" - : "com.android.tools.build:gradle:${androidPluginVersion}", + return [ + "com.android.tools.build:gradle", "org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlinVersion}", + "de.undercouch:gradle-download-task:5.6.0", + "com.facebook.react:react-native-gradle-plugin", ] - - if (autodetectReactNativeVersion || enableNewArchitecture) { - dependencies << "com.facebook.react:react-native-gradle-plugin" - dependencies << "de.undercouch:gradle-download-task:5.6.0" - } - - return dependencies } } diff --git a/android/gradle-wrapper.js b/android/gradle-wrapper.js index 869928cdf..e136566f4 100644 --- a/android/gradle-wrapper.js +++ b/android/gradle-wrapper.js @@ -39,11 +39,6 @@ const GRADLE_VERSIONS = [ [v(0, 79, 0), [v(8, 13, 0), "8.13"], [INT_MAX, ""]], // 0.79: [8.13, *) [v(0, 78, 0), [v(8, 12, 0), "8.12"], [INT_MAX, ""]], // 0.78: [8.12, *) [v(0, 76, 0), [v(8, 11, 1), "8.11.1"], [INT_MAX, ""]], // 0.76: [8.11.1, *) - [v(0, 75, 0), [v(8, 8, 0), "8.8"], [v(8, 9, 0), "8.8"]], // 0.75: [8.8, 8.9) - [v(0, 74, 0), [v(8, 6, 0), "8.6"], [v(8, 9, 0), "8.8"]], // 0.74: [8.6, 8.9) - [v(0, 73, 0), [v(8, 3, 0), "8.3"], [v(8, 9, 0), "8.8"]], // 0.73: [8.3, 8.9) - [v(0, 72, 0), [v(8, 1, 1), "8.1.1"], [v(8, 3, 0), "8.2.1"]], // 0.72: [8.1.1, 8.3) - [0, [v(7, 5, 1), "7.6.4"], [v(8, 0, 0), "7.6.4"]], // <0.72: [7.5.1, 8.0.0) ]; /** diff --git a/android/gradle.properties b/android/gradle.properties index c40976145..272b1be34 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -25,11 +25,11 @@ org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryEr # https://developer.android.com/topic/libraries/support-library/androidx-rn android.useAndroidX=true # Automatically convert third-party libraries to use AndroidX -android.enableJetifier=true +#android.enableJetifier=true # Failed to transform '/~/bcprov-jdk15on-1.68.jar' using Jetifier. # Reason: IllegalArgumentException, message: Unsupported class file major version 59. -android.jetifier.ignorelist=bcprov-jdk15on +#android.jetifier.ignorelist=bcprov-jdk15on # Kotlin code style for this project: "official" or "obsolete": kotlin.code.style=official diff --git a/android/react-native.gradle b/android/react-native.gradle index a7e913beb..3b4161dcf 100644 --- a/android/react-native.gradle +++ b/android/react-native.gradle @@ -11,30 +11,13 @@ ext.isBridgelessEnabled = { Project project, boolean isNewArchEnabled -> def version = getPackageVersionNumber("react-native", project.rootDir) if (version >= v(0, 82, 0)) { - if (bridgelessEnabled != null) { + if (bridgelessEnabled == "false") { logger.warn("WARNING: As of 0.82, bridgeless can no longer be disabled") } return true } - if (bridgelessEnabled != "false") { - def isSupported = version == 0 || version >= v(0, 73, 0) - - if (bridgelessEnabled == "true") { - if (!isSupported) { - logger.warn([ - "WARNING: react-native 0.73 or greater is required for", - "Bridgeless Mode — disable `bridgelessEnabled` in your", - "`gradle.properties` or upgrade `react-native`" - ].join(" ")) - } - return isSupported - } - - // https://github.com/facebook/react-native/commit/fe337f25be65b67dc3d8d99d26a61ffd26985dd8 - def isEnabledByDefault = version == 0 || version >= v(0, 74, 0) - return isSupported && isEnabledByDefault - } + return bridgelessEnabled != "false" } return false } @@ -49,23 +32,11 @@ ext.isNewArchitectureEnabled = { Project project -> def version = getPackageVersionNumber("react-native", project.rootDir) if (version >= v(0, 82, 0)) { - if (newArchEnabled != null) { + if (newArchEnabled == "false") { logger.warn("WARNING: As of 0.82, New Architecture can no longer be disabled") } return true } - if (newArchEnabled == "true") { - def isSupported = version == 0 || version >= v(0, 71, 0) - if (!isSupported) { - throw new GradleException([ - "react-native 0.71 or greater is required for New Architecture", - "— disable `newArchEnabled` in your `gradle.properties` or", - "upgrade `react-native`" - ].join(" ")) - } - return isSupported - } - - return false + return newArchEnabled == "true" } diff --git a/common/AppRegistry.cpp b/common/AppRegistry.cpp index 37b75fe25..efc483aee 100644 --- a/common/AppRegistry.cpp +++ b/common/AppRegistry.cpp @@ -9,32 +9,18 @@ using facebook::jsi::String; namespace { - constexpr char kFbBatchedBridgeId[] = "__fbBatchedBridge"; constexpr char kRNAppRegistryId[] = "RN$AppRegistry"; Array GetRegisteredAppKeys(Runtime &runtime) { auto global = runtime.global(); - if (global.hasProperty(runtime, kRNAppRegistryId)) { // >= 0.73 - // const appKeys = RN$AppRegistry.getAppKeys(); - auto registry = global.getProperty(runtime, kRNAppRegistryId); - if (registry.isObject()) { - auto getAppKeys = std::move(registry).asObject(runtime).getPropertyAsFunction( - runtime, "getAppKeys"); - return getAppKeys.call(runtime, nullptr, 0).asObject(runtime).asArray(runtime); - } - } else if (global.hasProperty(runtime, kFbBatchedBridgeId)) { // < 0.73 - // const appRegistry = __fbBatchedBridge.getCallableModule("AppRegistry"); - auto fbBatchedBridge = global.getPropertyAsObject(runtime, kFbBatchedBridgeId); - auto getCallableModule = - fbBatchedBridge.getPropertyAsFunction(runtime, "getCallableModule"); - auto appRegistry = - getCallableModule.callWithThis(runtime, fbBatchedBridge, "AppRegistry") - .asObject(runtime); - - // const appKeys = appRegistry.getAppKeys(); - auto getAppKeys = appRegistry.getPropertyAsFunction(runtime, "getAppKeys"); - return getAppKeys.callWithThis(runtime, appRegistry).asObject(runtime).asArray(runtime); + + // const appKeys = RN$AppRegistry.getAppKeys(); + auto registry = global.getProperty(runtime, kRNAppRegistryId); + if (registry.isObject()) { + auto getAppKeys = + std::move(registry).asObject(runtime).getPropertyAsFunction(runtime, "getAppKeys"); + return getAppKeys.call(runtime, nullptr, 0).asObject(runtime).asArray(runtime); } return Array(runtime, 0); diff --git a/example/android/build.gradle b/example/android/build.gradle index 602e4cc78..3e00c032b 100644 --- a/example/android/build.gradle +++ b/example/android/build.gradle @@ -21,23 +21,3 @@ buildscript { } } } - -allprojects { - repositories { - { - def searchDir = rootDir.toPath() - do { - def p = searchDir.resolve("node_modules/react-native/android") - if (p.toFile().exists()) { - maven { - url = p.toRealPath().toString() - } - break - } - } while (searchDir = searchDir.getParent()) - // As of 0.80, React Native is no longer installed from npm - }() - mavenCentral() - google() - } -} diff --git a/example/android/gradle.properties b/example/android/gradle.properties index 6a987572e..a3e761121 100644 --- a/example/android/gradle.properties +++ b/example/android/gradle.properties @@ -25,7 +25,7 @@ org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryEr # https://developer.android.com/topic/libraries/support-library/androidx-rn android.useAndroidX=true # Automatically convert third-party libraries to use AndroidX -android.enableJetifier=false +#android.enableJetifier=true # Jetifier randomly fails on these libraries #android.jetifier.ignorelist=hermes-android,react-android diff --git a/example/babel.config.js b/example/babel.config.js index 4d3f37339..ffff9ce44 100644 --- a/example/babel.config.js +++ b/example/babel.config.js @@ -1,10 +1,4 @@ module.exports = { - presets: (() => { - try { - return [require.resolve("@react-native/babel-preset")]; - } catch (_) { - return ["module:metro-react-native-babel-preset"]; - } - })(), + presets: [require.resolve("@react-native/babel-preset")], plugins: [[require("@rnx-kit/polyfills")]], }; diff --git a/example/src/App.tsx b/example/src/App.tsx index 4457f2e55..6a61b08b5 100644 --- a/example/src/App.tsx +++ b/example/src/App.tsx @@ -15,7 +15,6 @@ import { Separator } from "./Separator"; import { getHermesVersion, isBridgeless, - isConcurrentReactEnabled, isFabricInstance, ReactNativeVersion, } from "./core"; @@ -40,7 +39,7 @@ function useIsFabricComponent() { return [isFabric, setter] as const; } -export function App(props: AppProps): React.ReactElement { +export function App(_props: AppProps): React.ReactElement { const isDarkMode = useColorScheme() === "dark"; const styles = useStyles(); const [isFabric, setIsFabric] = useIsFabricComponent(); @@ -65,9 +64,7 @@ export function App(props: AppProps): React.ReactElement { Fabric - - Concurrent React - + Concurrent React Bridgeless diff --git a/example/src/core.ts b/example/src/core.ts index 1d526d8a7..db9eaccbf 100644 --- a/example/src/core.ts +++ b/example/src/core.ts @@ -53,24 +53,13 @@ export function isBridgeless() { return "RN$Bridgeless" in global && global.RN$Bridgeless === true; } -export function isConcurrentReactEnabled( - props: { concurrentRoot?: boolean }, - isFabric: boolean -): boolean { - const { major, minor } = ReactNativeVersion; - const version = major * 10000 + minor; - // As of 0.74, it won't be possible to opt-out: - // https://github.com/facebook/react-native/commit/30d186c3683228d4fb7a42f804eb2fdfa7c8ac03 - return isFabric && (version >= 74 || props.concurrentRoot !== false); -} - export function isFabricInstance( ref: NativeSyntheticEvent["currentTarget"] ): boolean { return Boolean( - // @ts-expect-error — https://github.com/facebook/react-native/blob/0.72-stable/packages/react-native/Libraries/Renderer/public/ReactFabricPublicInstanceUtils.js + // @ts-expect-error — https://github.com/facebook/react-native/blob/0.76-stable/packages/react-native/Libraries/ReactNative/ReactFabricPublicInstance/ReactFabricPublicInstanceUtils.js ref["__nativeTag"] || - // @ts-expect-error — https://github.com/facebook/react-native/blob/0.72-stable/packages/react-native/Libraries/Renderer/public/ReactFabricPublicInstanceUtils.js + // @ts-expect-error — https://github.com/facebook/react-native/blob/0.76-stable/packages/react-native/Libraries/ReactNative/ReactFabricPublicInstance/ReactFabricPublicInstanceUtils.js ref["_internalInstanceHandle"]?.stateNode?.canonical ); } diff --git a/ios/ReactTestApp/React+Compatibility.m b/ios/ReactTestApp/React+Compatibility.m index 7f55efdde..1594b15ea 100644 --- a/ios/ReactTestApp/React+Compatibility.m +++ b/ios/ReactTestApp/React+Compatibility.m @@ -47,63 +47,11 @@ void RTADisableRemoteDebugging() #endif } -// MARK: - [0.71.13] The additional `inlineSourceMap:` was added in 0.71.13 -// See https://github.com/facebook/react-native/commit/f7219ec02d71d2f0f6c71af4d5c3d4850a898fd8 - NSURL *RTADefaultJSBundleURL() { -#if REACT_NATIVE_VERSION < MAKE_VERSION(0, 71, 13) - return [RCTBundleURLProvider jsBundleURLForBundleRoot:@"index" - packagerHost:@"localhost" - enableDev:YES - enableMinification:NO]; -#else return [RCTBundleURLProvider jsBundleURLForBundleRoot:@"index" packagerHost:@"localhost" enableDev:YES enableMinification:NO inlineSourceMap:YES]; -#endif } - -// MARK: - [0.70.0] Alerts don't show when using UIScene -// See https://github.com/facebook/react-native/pull/35716 - -#if !TARGET_OS_OSX && REACT_NATIVE_VERSION < MAKE_VERSION(0, 72, 0) - -#import -#import - -@implementation RCTAlertController (ReactTestApp) - -+ (void)initialize -{ - if ([self class] != [RCTAlertController class]) { - return; - } - - if (@available(iOS 13.0, *)) { - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - RTASwizzleSelector([self class], @selector(hide), @selector(rta_hide)); - RTASwizzleSelector( - [self class], @selector(show:completion:), @selector(rta_show:completion:)); - }); - } -} - -- (void)rta_hide -{ - // noop -} - -- (void)rta_show:(BOOL)animated completion:(void (^)(void))completion -{ - [[RCTKeyWindow() rootViewController] presentViewController:self - animated:animated - completion:completion]; -} - -@end - -#endif // !TARGET_OS_OSX && REACT_NATIVE_VERSION < 0.72.0 diff --git a/ios/app.mjs b/ios/app.mjs index 353b21cda..454da211c 100644 --- a/ios/app.mjs +++ b/ios/app.mjs @@ -8,7 +8,6 @@ import { isMain, readTextFile, toVersionNumber, - v, } from "../scripts/helpers.js"; import { cp_r, mkdir_p, rm_r } from "../scripts/utils/filesystem.mjs"; import { generateAssetsCatalogs } from "./assetsCatalog.mjs"; @@ -78,31 +77,6 @@ function exportNodeBinaryPath(projectRoot, destination, fs = nodefs) { ); } -/** - * @param {string} reactNativePath - * @param {number} reactNativeVersion - * @returns {string | undefined} - */ -function findCommunityAutolinkingScriptPath( - reactNativePath, - reactNativeVersion, - fs = nodefs -) { - // As of 0.75, we should use `use_native_modules!` from `react-native` instead - if (reactNativeVersion < v(0, 75, 0)) { - const pkgPath = findFile( - "node_modules/@react-native-community/cli-platform-ios", - reactNativePath, - fs - ); - if (pkgPath) { - return path.join(pkgPath, "native_modules.rb"); - } - } - - return undefined; -} - /** * @param {string} projectRoot * @returns {string} @@ -238,12 +212,7 @@ export function generateProject( reactNativePath: path.resolve(reactNativePath), reactNativeVersion, reactNativeHostPath: findReactNativeHostPath(projectRoot, fs), - communityAutolinkingScriptPath: findCommunityAutolinkingScriptPath( - reactNativePath, - reactNativeVersion, - fs - ), - useHermes: isHermesEnabled(targetPlatform, reactNativeVersion, options), + useHermes: isHermesEnabled(reactNativeVersion, options), useNewArch: isNewArchEnabled(reactNativeVersion, options), useBridgeless: isBridgelessEnabled(reactNativeVersion, options), buildSettings: {}, diff --git a/ios/features.mjs b/ios/features.mjs index 90f9f5f71..aca7af07b 100644 --- a/ios/features.mjs +++ b/ios/features.mjs @@ -1,5 +1,5 @@ // @ts-check -/** @import { ApplePlatform, JSONObject } from "../scripts/types.ts"; */ +/** @import { JSONObject } from "../scripts/types.ts"; */ import { v } from "../scripts/helpers.js"; /** @@ -9,13 +9,6 @@ function isNewArchExclusive(reactNativeVersion) { return reactNativeVersion >= v(0, 82, 0); } -/** - * @param {number} reactNativeVersion - */ -function supportsNewArch(reactNativeVersion) { - return reactNativeVersion === 0 || reactNativeVersion >= v(0, 71, 0); -} - /** * @param {number} reactNativeVersion * @param {JSONObject} options @@ -26,10 +19,6 @@ export function isNewArchEnabled(reactNativeVersion, options) { return true; } - if (!supportsNewArch(reactNativeVersion)) { - return false; - } - const newArchEnabled = process.env["RCT_NEW_ARCH_ENABLED"]; if (typeof newArchEnabled === "string") { return newArchEnabled !== "0"; @@ -69,29 +58,16 @@ export function isBridgelessEnabled(reactNativeVersion, options) { } /** - * @param {ApplePlatform} platform * @param {number} reactNativeVersion * @param {JSONObject} options * @returns {boolean | "from-source"} */ -export function isHermesEnabled(platform, reactNativeVersion, options) { +export function isHermesEnabled(reactNativeVersion, options) { if (reactNativeVersion < v(0, 80, 0)) { const useHermes = process.env["USE_HERMES"]; - const enabled = - typeof useHermes === "string" - ? useHermes === "1" - : options["hermesEnabled"] === true; - - // Hermes prebuilds for visionOS was introduced in 0.76 - if ( - enabled && - platform === "visionos" && - reactNativeVersion < v(0, 76, 0) - ) { - return "from-source"; - } - - return enabled; + return typeof useHermes === "string" + ? useHermes === "1" + : options["hermesEnabled"] === true; } return true; diff --git a/ios/pod_helpers.rb b/ios/pod_helpers.rb index f4f72ff37..b481fb476 100644 --- a/ios/pod_helpers.rb +++ b/ios/pod_helpers.rb @@ -33,17 +33,9 @@ def use_hermes?(options) use_hermes != false end -def use_new_architecture!(options, react_native_version) +def use_new_architecture!(options, _react_native_version) return unless options[:use_new_arch] - if react_native_version < v(0, 76, 0) - Pod::UI.warn( - 'As of writing, New Architecture (Fabric) is still experimental and ' \ - 'subject to change. For more information, please see ' \ - 'https://reactnative.dev/docs/next/new-architecture-intro.' - ) - end - options[:fabric_enabled] = true options[:new_arch_enabled] = true ENV['RCT_NEW_ARCH_ENABLED'] = '1' diff --git a/ios/test_app.rb b/ios/test_app.rb index a408beae7..85bd40a56 100644 --- a/ios/test_app.rb +++ b/ios/test_app.rb @@ -28,13 +28,11 @@ def target_product_type(target) end def react_native_pods(version) - if version.zero? || version >= v(0, 71, 0) - 'use_react_native-0.71' - elsif version >= v(0, 70, 0) - 'use_react_native-0.70' - else + unless version.zero? || version >= v(0, 71, 0) raise "Unsupported React Native version: #{version}" end + + 'use_react_native-0.71' end def validate_resources(resources, app_dir) @@ -139,7 +137,6 @@ def make_project!(project_root, target_platform, options) :react_native_path => project['reactNativePath'], :react_native_version => project['reactNativeVersion'], :react_native_host_path => project['reactNativeHostPath'], - :community_autolinking_script_path => project['communityAutolinkingScriptPath'], :use_hermes => project['useHermes'], :use_new_arch => project['useNewArch'], :use_bridgeless => project['useBridgeless'], @@ -159,14 +156,7 @@ def use_test_app_internal!(target_platform, options) project_target = make_project!(project_root, target_platform, options) xcodeproj_dst, platforms = project_target.values_at(:xcodeproj_path, :platforms) - if project_target[:use_new_arch] || project_target[:react_native_version] >= v(0, 73, 0) - install! 'cocoapods', :deterministic_uuids => false - end - - # As of 0.75, we should use `use_native_modules!` from `react-native` instead - if project_target[:community_autolinking_script_path].is_a? String - require_relative(project_target[:community_autolinking_script_path]) - end + install! 'cocoapods', :deterministic_uuids => false if project_target[:use_new_arch] begin platform :ios, platforms[:ios] if target_platform == :ios @@ -212,11 +202,6 @@ def use_test_app_internal!(target_platform, options) case target.name when /\AReact/, 'RCT-Folly', 'SocketRocket', 'Yoga', 'fmt', 'glog', 'libevent' target.build_configurations.each do |config| - # TODO: Drop `_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION` when - # we no longer support 0.72 - config.build_settings[GCC_PREPROCESSOR_DEFINITIONS] ||= ['$(inherited)'] - config.build_settings[GCC_PREPROCESSOR_DEFINITIONS] << - '_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION=1' config.build_settings[WARNING_CFLAGS] ||= [] config.build_settings[WARNING_CFLAGS] << '-w' end diff --git a/ios/use_react_native-0.70.rb b/ios/use_react_native-0.70.rb deleted file mode 100644 index 0f3f40598..000000000 --- a/ios/use_react_native-0.70.rb +++ /dev/null @@ -1,29 +0,0 @@ -require 'open3' - -require_relative('pod_helpers') - -def include_react_native!(options) - react_native, project_root = options.values_at(:path, :rta_project_root) - - require_relative(File.join(project_root, react_native, 'scripts', 'react_native_pods')) - - use_react_native!( - path: react_native, - production: options.key?(:production) ? options[:production] : ENV['PRODUCTION'] == '1', - hermes_enabled: use_hermes?(options), - app_path: options[:app_path] || '..', - config_file_dir: options[:config_file_dir] || '' - ) - - # If we're using react-native@main, we'll also need to prepare - # `react-native-codegen`. - codegen = File.join(project_root, react_native, 'packages', 'react-native-codegen') - Open3.popen3('node scripts/build.js', :chdir => codegen) if File.directory?(codegen) - - lambda { |installer| - react_native_post_install(installer, react_native) - if defined?(__apply_Xcode_12_5_M1_post_install_workaround) - __apply_Xcode_12_5_M1_post_install_workaround(installer) - end - } -end diff --git a/ios/xcode.mjs b/ios/xcode.mjs index 35c45cd29..1905057a4 100644 --- a/ios/xcode.mjs +++ b/ios/xcode.mjs @@ -2,7 +2,7 @@ import { XMLBuilder, XMLParser } from "fast-xml-parser"; import * as nodefs from "node:fs"; import * as path from "node:path"; -import { findFile, readTextFile, v } from "../scripts/helpers.js"; +import { findFile, readTextFile } from "../scripts/helpers.js"; import { assertArray, assertObject, @@ -112,18 +112,6 @@ export function applyPreprocessorDefinitions({ preprocessors.push(`REACT_NATIVE_VERSION=${reactNativeVersion}`); - // In Xcode 15, `unary_function` and `binary_function` are no longer provided - // in C++17 and newer Standard modes. See Xcode release notes: - // https://developer.apple.com/documentation/xcode-release-notes/xcode-15-release-notes#Deprecations - // Upstream issue: https://github.com/facebook/react-native/issues/37748 - const enableCxx17RemovedUnaryBinaryFunction = - (reactNativeVersion >= v(0, 72, 0) && reactNativeVersion < v(0, 72, 5)) || - (reactNativeVersion >= v(0, 71, 0) && reactNativeVersion < v(0, 71, 4)) || - (reactNativeVersion > 0 && reactNativeVersion < v(0, 70, 14)); - if (enableCxx17RemovedUnaryBinaryFunction) { - preprocessors.push("_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION=1"); - } - if (useNewArch) { preprocessors.push("FOLLY_NO_CONFIG=1"); preprocessors.push("RCT_NEW_ARCH_ENABLED=1"); diff --git a/package.json b/package.json index 33f6dd138..04c3a9f06 100644 --- a/package.json +++ b/package.json @@ -98,12 +98,12 @@ "uuid": "^11.0.0" }, "peerDependencies": { - "@callstack/react-native-visionos": "0.73 - 0.79", + "@callstack/react-native-visionos": "0.76 - 0.79", "@expo/config-plugins": ">=5.0", - "react": "18.1 - 19.1", - "react-native": "0.70 - 0.82 || >=0.83.0-0 <0.83.0", - "react-native-macos": "^0.0.0-0 || 0.71 - 0.79", - "react-native-windows": "^0.0.0-0 || 0.70 - 0.79" + "react": "18.2 - 19.1", + "react-native": "0.76 - 0.82 || >=0.83.0-0 <0.83.0", + "react-native-macos": "^0.0.0-0 || 0.76 - 0.79", + "react-native-windows": "^0.0.0-0 || 0.76 - 0.79" }, "peerDependenciesMeta": { "@callstack/react-native-visionos": { @@ -153,7 +153,7 @@ "typescript": "^5.0.0" }, "engines": { - "node": ">=16.17" + "node": ">=18.12" }, "packageManager": "yarn@4.10.3", "resolutions": { diff --git a/plugins/reanimated.js b/plugins/reanimated.js index 20743c8b4..4f5d0706b 100644 --- a/plugins/reanimated.js +++ b/plugins/reanimated.js @@ -39,46 +39,15 @@ function installerFor(version, indent = " ") { const minor = v(0, 1, 0); const minorVersion = Math.trunc(version / minor) % minor; - if (version > 0 && version < v(0, 72, 0)) { - const header = [ - "#if !USE_FABRIC", - "#pragma clang diagnostic push", - '#pragma clang diagnostic ignored "-Wnullability-completeness"', - "", - `#define REACT_NATIVE_MINOR_VERSION ${minorVersion}`, - "#import ", - "", - "#if __has_include()", - "#import ", - "using ExecutorFactory = facebook::react::HermesExecutorFactory;", - "#elif __has_include()", - "#import ", - "using ExecutorFactory = facebook::react::HermesExecutorFactory;", - "#else", - "#import ", - "using ExecutorFactory = facebook::react::JSCExecutorFactory;", - "#endif", - "", - "#pragma clang diagnostic pop", - "#endif // !USE_FABRIC", - ].join("\n"); - const installer = [ - `${indent}const auto installer = reanimated::REAJSIExecutorRuntimeInstaller(bridge, nullptr);`, - `${indent}auto installBindings = facebook::react::RCTJSIExecutorRuntimeInstaller(installer);`, - `${indent}return std::make_unique(installBindings);`, - ].join("\n"); - return [header, installer]; - } else { - // As of React Native 0.72, we need to call `REAInitializer` instead. See - // https://github.com/software-mansion/react-native-reanimated/commit/a8206f383e51251e144cb9fd5293e15d06896df0. - const header = [ - "#if !USE_FABRIC", - `#define REACT_NATIVE_MINOR_VERSION ${minorVersion}`, - "#import ", - "#endif // !USE_FABRIC", - ].join("\n"); - return [header, `${indent}reanimated::REAInitializer(bridge);`]; - } + // As of React Native 0.72, we need to call `REAInitializer` instead. See + // https://github.com/software-mansion/react-native-reanimated/commit/a8206f383e51251e144cb9fd5293e15d06896df0. + const header = [ + "#if !USE_FABRIC", + `#define REACT_NATIVE_MINOR_VERSION ${minorVersion}`, + "#import ", + "#endif // !USE_FABRIC", + ].join("\n"); + return [header, `${indent}reanimated::REAInitializer(bridge);`]; } /** diff --git a/scripts/configure-projects.js b/scripts/configure-projects.js index ed30505b8..26d2cc2d6 100644 --- a/scripts/configure-projects.js +++ b/scripts/configure-projects.js @@ -11,14 +11,7 @@ const nodefs = require("node:fs"); const path = require("node:path"); const { generateAndroidManifest } = require("../android/android-manifest"); const { configureGradleWrapper } = require("../android/gradle-wrapper"); -const { - findFile, - findNearest, - getPackageVersion, - readTextFile, - toVersionNumber, - v, -} = require("./helpers"); +const { findFile, findNearest, readTextFile } = require("./helpers"); /** * Finds `react-native.config.[ts,mjs,cjs,js]`. @@ -76,52 +69,10 @@ function findReactNativeConfig(fs = nodefs) { throw new Error("Failed to find `react-native.config.[ts,mjs,cjs,js]`"); } -/** - * Returns the version number of a React Native dependency. - * @param {string} packageName - * @returns {number} - */ -const getRNPackageVersion = (() => { - const isTesting = "NODE_TEST_CONTEXT" in process.env; - - /** @type {Record} */ - let versions = {}; - - /** @type {(packageName: string) => number} */ - return (packageName, fs = nodefs) => { - if (isTesting || !versions[packageName]) { - const rnDir = path.dirname(require.resolve("react-native/package.json")); - const versionString = getPackageVersion(packageName, rnDir, fs); - versions[packageName] = toVersionNumber(versionString); - } - return versions[packageName]; - }; -})(); - /** * @returns {string | undefined} */ -function getAndroidPackageName(fs = nodefs) { - try { - const rncliAndroidVersion = getRNPackageVersion( - "@react-native-community/cli-platform-android", - fs - ); - if (rncliAndroidVersion < v(12, 3, 7)) { - // TODO: This block can be removed when we drop support for 0.72 - return undefined; - } - if ( - rncliAndroidVersion >= v(13, 0, 0) && - rncliAndroidVersion < v(13, 6, 9) - ) { - // TODO: This block can be removed when we drop support for 0.73 - return undefined; - } - } catch (_) { - // We're on 0.76 or later - } - +function getAndroidPackageName() { return "com.microsoft.reacttestapp"; } @@ -171,7 +122,7 @@ function configureProjects({ android, ios, windows }, fs = nodefs) { config.android = { sourceDir, manifestPath, - packageName: packageName || getAndroidPackageName(fs), + packageName: packageName || getAndroidPackageName(), }; configureGradleWrapper(sourceDir, fs); diff --git a/scripts/configure.mjs b/scripts/configure.mjs index 33d1ff12b..aad5cb943 100755 --- a/scripts/configure.mjs +++ b/scripts/configure.mjs @@ -24,7 +24,6 @@ import { readJSONFile, readTextFile, toVersionNumber, - v, } from "./helpers.js"; import { appManifest, @@ -77,11 +76,6 @@ export function error(message) { * @returns {Promise} */ async function findTemplateDir(targetVersion) { - if (toVersionNumber(targetVersion) < v(0, 75, 0)) { - // Let `getConfig` try to find the template inside `react-native` - return undefined; - } - const [major, minor = 0] = targetVersion.split("."); const output = await downloadPackage( "@react-native-community/template", @@ -296,17 +290,8 @@ export const getConfig = (() => { ...(!init ? undefined : { - // TODO: We will no longer need to consider `App.js` when we - // drop support for 0.70 - ...(fs.existsSync(path.join(templateDir, "App.tsx")) - ? { - "App.tsx": copyFrom(templateDir, "App.tsx"), - "tsconfig.json": copyFrom(templateDir, "tsconfig.json"), - } - : { - "App.js": copyFrom(templateDir, "App.js"), - }), ".bundle/config": bundleConfig(), + "App.tsx": copyFrom(templateDir, "App.tsx"), Gemfile: copyFrom(templateDir, "Gemfile"), "app.json": appManifest(name), "index.js": copyFrom(templateDir, "index.js"), @@ -314,13 +299,11 @@ export const getConfig = (() => { path.join(templateDir, "package.json"), fs ).replaceAll("HelloWorld", name), + "tsconfig.json": copyFrom(templateDir, "tsconfig.json"), }), }, oldFiles: [], scripts: { - // TODO: Remove this script when we drop support for 0.72 - // https://github.com/react-native-community/cli/commit/48d4c29bba4e8b16cbc8307bd1b4c5349f3651d8 - mkdist: `node -e "require('node:fs').mkdirSync('dist', { recursive: true, mode: 0o755 })"`, start: "react-native start", }, dependencies: {}, @@ -336,24 +319,14 @@ export const getConfig = (() => { "wrapper", "gradle-wrapper.jar" ), - "gradle/wrapper/gradle-wrapper.properties": (() => { - const gradleWrapperProperties = path.join( - testAppPath, - "example", - "android", - "gradle", - "wrapper", - "gradle-wrapper.properties" - ); - const props = readTextFile(gradleWrapperProperties); - if (targetVersionNum < v(0, 73, 0)) { - return props.replace( - /gradle-[.0-9]*-bin\.zip/, - "gradle-7.6.4-bin.zip" - ); - } - return props; - })(), + "gradle/wrapper/gradle-wrapper.properties": copyFrom( + testAppPath, + "example", + "android", + "gradle", + "wrapper", + "gradle-wrapper.properties" + ), "gradle.properties": gradleProperties(targetVersionNum), gradlew: copyFrom(testAppPath, "example", "android", "gradlew"), "gradlew.bat": copyFrom( @@ -368,7 +341,7 @@ export const getConfig = (() => { scripts: { android: "react-native run-android", "build:android": - "npm run mkdist && react-native bundle --entry-file index.js --platform android --dev true --bundle-output dist/main.android.jsbundle --assets-dest dist/res", + "react-native bundle --entry-file index.js --platform android --dev true --bundle-output dist/main.android.jsbundle --assets-dest dist/res", }, dependencies: {}, }, @@ -384,7 +357,7 @@ export const getConfig = (() => { ], scripts: { "build:ios": - "npm run mkdist && react-native bundle --entry-file index.js --platform ios --dev true --bundle-output dist/main.ios.jsbundle --assets-dest dist", + "react-native bundle --entry-file index.js --platform ios --dev true --bundle-output dist/main.ios.jsbundle --assets-dest dist", ios: "react-native run-ios", }, dependencies: {}, @@ -401,7 +374,7 @@ export const getConfig = (() => { ], scripts: { "build:macos": - "npm run mkdist && react-native bundle --entry-file index.js --platform macos --dev true --bundle-output dist/main.macos.jsbundle --assets-dest dist", + "react-native bundle --entry-file index.js --platform macos --dev true --bundle-output dist/main.macos.jsbundle --assets-dest dist", macos: `react-native run-macos --scheme ${name}`, }, dependencies: {}, @@ -418,7 +391,7 @@ export const getConfig = (() => { ], scripts: { "build:visionos": - "npm run mkdist && react-native bundle --entry-file index.js --platform ios --dev true --bundle-output dist/main.visionos.jsbundle --assets-dest dist", + "react-native bundle --entry-file index.js --platform ios --dev true --bundle-output dist/main.visionos.jsbundle --assets-dest dist", visionos: "react-native run-visionos", }, dependencies: {}, @@ -439,7 +412,7 @@ export const getConfig = (() => { ], scripts: { "build:windows": - "npm run mkdist && react-native bundle --entry-file index.js --platform windows --dev true --bundle-output dist/main.windows.bundle --assets-dest dist", + "react-native bundle --entry-file index.js --platform windows --dev true --bundle-output dist/main.windows.bundle --assets-dest dist", windows: "react-native run-windows", }, dependencies: {}, diff --git a/scripts/init.mjs b/scripts/init.mjs index 633827e24..68419cc81 100755 --- a/scripts/init.mjs +++ b/scripts/init.mjs @@ -9,7 +9,7 @@ import { getDefaultPlatformPackageName, validatePlatforms, } from "./configure.mjs"; -import { memo, readJSONFile, toVersionNumber, v } from "./helpers.js"; +import { memo, readJSONFile } from "./helpers.js"; import * as colors from "./utils/colors.mjs"; import { downloadPackage, fetchPackageMetadata } from "./utils/npm.mjs"; import { parseArgs } from "./utils/parseargs.mjs"; @@ -49,7 +49,7 @@ const getInstalledVersion = memo(() => { * * Checks the following in order: * - * - Command line flag, e.g. `--version 0.70` + * - Command line flag, e.g. `--version 0.81` * - Currently installed `react-native` version * - Latest version from npm * @@ -116,18 +116,10 @@ async function getVersion(platforms) { */ async function fetchTemplate(platforms) { const version = await getVersion(platforms); - const useTemplatePackage = toVersionNumber(version) >= v(0, 75, 0); - if (!useTemplatePackage && getInstalledVersion() === version) { - const rnManifest = getInstalledReactNativeManifest(); - if (rnManifest) { - return [version, path.join(path.dirname(rnManifest), "template")]; - } - } - - const template = useTemplatePackage - ? "@react-native-community/template" - : "react-native"; - const output = await downloadPackage(template, version); + const output = await downloadPackage( + "@react-native-community/template", + version + ); return [version, path.join(output, "template")]; } diff --git a/scripts/internal/set-react-version.mts b/scripts/internal/set-react-version.mts index 04dac6570..645d47e29 100644 --- a/scripts/internal/set-react-version.mts +++ b/scripts/internal/set-react-version.mts @@ -5,13 +5,7 @@ import * as fs from "node:fs"; import * as path from "node:path"; import * as util from "node:util"; -import { - isMain, - readJSONFile, - readTextFile, - toVersionNumber, - v, -} from "../helpers.js"; +import { isMain, readJSONFile } from "../helpers.js"; import type { Manifest } from "../types.js"; import { writeJSONFile } from "../utils/filesystem.mjs"; import { fetchPackageMetadata, npmRegistryBaseURL } from "../utils/npm.mjs"; @@ -32,41 +26,6 @@ function keys>(obj: T): (keyof T)[] { return Object.keys(obj) as (keyof T)[]; } -function searchReplaceInFile( - filename: string, - searchValue: string | RegExp, - replaceValue: string -): void { - const current = readTextFile(filename); - const updated = current.replace(searchValue, replaceValue); - if (updated !== current) { - fs.writeFileSync(filename, updated); - } -} - -/** - * Disables [Jetifier](https://developer.android.com/tools/jetifier). - * - * Jetifier is only necessary when you depend on code that has not yet migrated - * to AndroidX. If we only deal with modern code, disabling it makes builds - * slightly faster. - */ -function disableJetifier() { - return searchReplaceInFile( - "example/android/gradle.properties", - "android.enableJetifier=true", - "android.enableJetifier=false" - ); -} - -function disableWebStorage() { - return searchReplaceInFile( - "example/package.json", - /\s+"@react-native-webapis\/web-storage":.*/, - "" - ); -} - /** * Infer the React Native version an out-of-tree platform package is based on. */ @@ -122,6 +81,22 @@ function fetchPackageInfo(pkg: string, version: string): Promise { }); } +/** + * Fetches the template manifest for the specified React Native version. + */ +function fetchTemplateManifest(version: string): Promise { + const url = `https://raw.githubusercontent.com/react-native-community/template/refs/heads/${version}-stable/template/package.json`; + console.log(`Fetching template manifest from ${url}`); + return fetch(url, { + headers: { + Accept: + "application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*", + }, + }) + .then((res) => res.text()) + .then((text) => JSON.parse(text)); +} + /** * Fetches the latest react-native-windows@canary information via NuGet. */ @@ -175,61 +150,35 @@ function fetchReactNativeWindowsCanaryInfoViaNuGet(): Promise { */ async function resolveCommonDependencies( v: string, - { dependencies = {}, peerDependencies = {} }: Manifest + { peerDependencies = {} }: Manifest ): Promise> { - const [rnBabelPresetVersion, rnMetroConfigVersion, metroBabelPresetVersion] = + const [devDependencies, rnBabelPresetVersion, rnMetroConfigVersion] = await (async () => { if (["^", "canary", "nightly"].some((tag) => v.includes(tag))) { - return [v, v, undefined]; + return [{}, v, v]; } const [ + { devDependencies }, { version: rnBabelPresetVersion }, { version: rnMetroConfigVersion }, - { version: metroBabelPresetVersion }, ] = await Promise.all([ + fetchTemplateManifest(v), fetchPackageInfo("@react-native/babel-preset", v), fetchPackageInfo("@react-native/metro-config", v), - (async () => { - // Metro bumps and publishes all packages together, meaning we can use - // `metro-react-native-babel-transformer` to determine the version of - // `metro-react-native-babel-preset` that should be used. - const version = dependencies["metro-react-native-babel-transformer"]; - if (version) { - return { version }; - } - - // `metro-react-native-babel-transformer` is no longer a direct - // dependency of `react-native`. As of 0.72, we should go through - // `@react-native-community/cli-plugin-metro` instead. - const cliVersion = dependencies["@react-native-community/cli"]; - if (!cliVersion) { - // `@react-native-community/cli` is no longer a direct dependency in - // 0.73. We should be using `@react-native/babel-preset` instead. - return {}; - } - - const metroPluginInfo = await fetchPackageInfo( - "@react-native-community/cli-plugin-metro", - cliVersion.replace("^", "").split(".").slice(0, 2).join(".") - ); - return { version: metroPluginInfo.dependencies?.["metro"] }; - })(), ]); return [ + devDependencies ?? {}, rnBabelPresetVersion, rnMetroConfigVersion, - metroBabelPresetVersion, ]; })(); - // Starting with 0.76, `react-native` no longer depends on - // `@react-native-community/cli` - const rncli = dependencies["@react-native-community/cli"] ?? "latest"; + const rncli = devDependencies["@react-native-community/cli"] ?? "latest"; const rncliAndroid = - dependencies["@react-native-community/cli-platform-android"] ?? rncli; + devDependencies["@react-native-community/cli-platform-android"] ?? rncli; const rncliIOS = - dependencies["@react-native-community/cli-platform-ios"] ?? rncli; + devDependencies["@react-native-community/cli-platform-ios"] ?? rncli; return { "@react-native-community/cli": rncli, @@ -237,7 +186,6 @@ async function resolveCommonDependencies( "@react-native-community/cli-platform-ios": rncliIOS, "@react-native/babel-preset": rnBabelPresetVersion, "@react-native/metro-config": rnMetroConfigVersion, - "metro-react-native-babel-preset": metroBabelPresetVersion, // Replace range to avoid React version mismatch react: peerDependencies["react"].replace(/^\^/, ""), }; @@ -398,18 +346,6 @@ if (isMain(import.meta.url)) { process.exitCode = 1; } else { const { "core-only": coreOnly, overrides } = values; - setReactVersion(version, coreOnly, JSON.parse(overrides)).then(() => { - const numVersion = VALID_TAGS.includes(version) - ? Number.MAX_SAFE_INTEGER - : toVersionNumber(version); - if (numVersion >= v(0, 74, 0)) { - disableJetifier(); - } - - // `@react-native-webapis/web-storage` is not compatible with codegen 0.71 - if (numVersion < v(0, 72, 0)) { - disableWebStorage(); - } - }); + setReactVersion(version, coreOnly, JSON.parse(overrides)); } } diff --git a/scripts/template.mjs b/scripts/template.mjs index 89efb1c32..c088bc5d3 100644 --- a/scripts/template.mjs +++ b/scripts/template.mjs @@ -71,28 +71,6 @@ export function buildGradle() { " }", " }", "}", - "", - // TODO: Remove this block when we drop support for 0.70 - // https://github.com/facebook/react-native/commit/51a48d2e2c64a18012692b063368e369cd8ff797 - "allprojects {", - " repositories {", - " {", - " def searchDir = rootDir.toPath()", - " do {", - ' def p = searchDir.resolve("node_modules/react-native/android")', - " if (p.toFile().exists()) {", - " maven {", - " url = p.toRealPath().toString()", - " }", - " break", - " }", - " } while (searchDir = searchDir.getParent())", - " // As of 0.80, React Native is no longer installed from npm", - " }()", - " mavenCentral()", - " google()", - " }", - "}", "" ); } @@ -110,14 +88,10 @@ export function bundleConfig() { } /** - * @param {number} targetVersion Target React Native version + * @param {number} _targetVersion Target React Native version * @returns {string} */ -export function gradleProperties(targetVersion) { - // https://github.com/facebook/react-native/commit/14ccf6bc9c40a51e913bb89a67b114f035bf77cd - const enableJetifier = targetVersion < v(0, 75, 0) ? "" : "#"; - // https://reactnative.dev/blog/2024/10/23/the-new-architecture-is-here - const enableNewArch = targetVersion >= v(0, 76, 0) ? "" : "#"; +export function gradleProperties(_targetVersion) { return join( "# Project-wide Gradle settings.", "", @@ -146,9 +120,9 @@ export function gradleProperties(targetVersion) { "# https://developer.android.com/topic/libraries/support-library/androidx-rn", "android.useAndroidX=true", "# Automatically convert third-party libraries to use AndroidX", - `${enableJetifier}android.enableJetifier=true`, + `#android.enableJetifier=true`, "# Jetifier randomly fails on these libraries", - `${enableJetifier}android.jetifier.ignorelist=hermes-android,react-android`, + `#android.jetifier.ignorelist=hermes-android,react-android`, "", "# Use this property to specify which architecture you want to build.", "# You can also override it from the CLI using", @@ -161,7 +135,7 @@ export function gradleProperties(targetVersion) { "# to write custom TurboModules/Fabric components OR use libraries that", "# are providing them.", "# Note that this is incompatible with web debugging.", - `${enableNewArch}newArchEnabled=true`, + `newArchEnabled=true`, "#bridgelessEnabled=true", "", "# Uncomment the line below to build React Native from source.", diff --git a/scripts/types.ts b/scripts/types.ts index 946280081..9c17be4be 100644 --- a/scripts/types.ts +++ b/scripts/types.ts @@ -137,7 +137,6 @@ export type ProjectConfiguration = { reactNativePath: string; reactNativeVersion: number; reactNativeHostPath: string; - communityAutolinkingScriptPath?: string; singleApp?: string; useHermes: boolean | "from-source"; useNewArch: boolean; diff --git a/test-app.gradle b/test-app.gradle index ea080886a..23aa687ab 100644 --- a/test-app.gradle +++ b/test-app.gradle @@ -14,11 +14,6 @@ applyConfigPlugins(rootDir, testAppDir) def reactNativeDir = file(findNodeModulesPath("react-native", rootDir)) -def importLegacyAutolinkingModule = { File startDir -> - def cliAndroidDir = findNodeModulesPath("@react-native-community/cli-platform-android", startDir) - apply(from: "${cliAndroidDir}/native_modules.gradle") -} - ext.applyTestAppSettings = { DefaultSettings settings -> settings.include(":app") settings.include(":support") @@ -28,28 +23,18 @@ ext.applyTestAppSettings = { DefaultSettings settings -> settings.project(":support") .projectDir = file("${testAppDir}/android/support") - def reactNativeVersion = getPackageVersionNumber("react-native", rootDir) - - def reactNativeGradlePlugin = - reactNativeVersion >= v(0, 72, 0) - ? findNodeModulesPath("@react-native/gradle-plugin", reactNativeDir) - : findNodeModulesPath("react-native-gradle-plugin", reactNativeDir) + def reactNativeGradlePlugin = findNodeModulesPath("@react-native/gradle-plugin", reactNativeDir) if (reactNativeGradlePlugin != null) { settings.includeBuild(reactNativeGradlePlugin) } - if (reactNativeVersion == 0 || reactNativeVersion >= v(0, 75, 0)) { - // https://github.com/facebook/react-native/blob/b0c0bb45911434ea654ba7e2feff4686061eba7a/packages/react-native-gradle-plugin/settings-plugin/src/main/kotlin/com/facebook/react/ReactSettingsExtension.kt#L39 - def output = file("${rootDir}/app/build/generated/rnta/autolinking.json") - def projectRoot = file(findFile("package.json").getParent()) - def dependencies = autolinkModules(projectRoot, output, testAppDir) - dependencies.each { path, info -> - settings.include(path) - settings.project(path).projectDir = file(info.projectDir) - } - } else { - importLegacyAutolinkingModule(reactNativeDir) - applyNativeModulesSettingsGradle(settings) + // https://github.com/facebook/react-native/blob/b0c0bb45911434ea654ba7e2feff4686061eba7a/packages/react-native-gradle-plugin/settings-plugin/src/main/kotlin/com/facebook/react/ReactSettingsExtension.kt#L39 + def output = file("${rootDir}/app/build/generated/rnta/autolinking.json") + def projectRoot = file(findFile("package.json").getParent()) + def dependencies = autolinkModules(projectRoot, output, testAppDir) + dependencies.each { path, info -> + settings.include(path) + settings.project(path).projectDir = file(info.projectDir) } if (settings.hasProperty("react.buildFromSource") && settings["react.buildFromSource"] == "true") { @@ -67,10 +52,7 @@ ext.applyTestAppSettings = { DefaultSettings settings -> ext.applyTestAppModule = { Project project -> def reactNativeVersion = getPackageVersionNumber("react-native", rootDir) - if (reactNativeVersion >= 0 && reactNativeVersion < v(0, 75, 0)) { - importLegacyAutolinkingModule(reactNativeDir) - applyNativeModulesAppBuildGradle(project) - } else if (reactNativeVersion >= v(0, 82, 0)) { + if (reactNativeVersion >= v(0, 82, 0)) { // Ensure community modules can continue using `isNewArchEnabled()` to // determine whether New Architecture is enabled when it is enabled by // default in React Native 0.82 and later. diff --git a/test/android/gradle-wrapper.test.ts b/test/android/gradle-wrapper.test.ts index 1392a958d..ca92a4485 100644 --- a/test/android/gradle-wrapper.test.ts +++ b/test/android/gradle-wrapper.test.ts @@ -140,16 +140,6 @@ describe("configureGradleWrapper()", () => { ["8.12", "0.79.0", "gradle-8.13-bin.zip"], ["8.11.1", "0.78.0", "gradle-8.12-bin.zip"], ["8.9", "0.76.0", "gradle-8.11.1-bin.zip"], - ["8.9", "0.75.0", "gradle-8.8-bin.zip"], - ["8.7", "0.75.0", "gradle-8.8-bin.zip"], - ["8.9", "0.74.0", "gradle-8.8-bin.zip"], - ["8.5", "0.74.0", "gradle-8.6-bin.zip"], - ["8.9", "0.73.0", "gradle-8.8-bin.zip"], - ["8.2.1", "0.73.0", "gradle-8.3-bin.zip"], - ["8.3", "0.72.0", "gradle-8.2.1-bin.zip"], - ["8.1", "0.72.0", "gradle-8.1.1-bin.zip"], - ["8.0", "0.71.0", "gradle-7.6.4-bin.zip"], - ["7.5", "0.71.0", "gradle-7.6.4-bin.zip"], ]; for (const [gradleVersion, rnVersion, expected] of cases) { written = ""; @@ -200,15 +190,6 @@ describe("configureGradleWrapper()", () => { ["8.13", "0.79.0"], ["8.12", "0.78.0"], ["8.11.1", "0.76.0"], - ["8.8", "0.75.0"], - ["8.8", "0.74.0"], - ["8.8", "0.73.0"], - ["8.2", "0.72.0"], - ["8.6", "0.74.0"], - ["8.3", "0.73.0"], - ["8.1.1", "0.72.0"], - ["7.6.4", "0.71.0"], - ["7.5.1", "0.71.0"], ]; for (const [gradleVersion, rnVersion] of cases) { const fs = mockfs(gradleVersion, rnVersion); diff --git a/test/configure-projects.test.ts b/test/configure-projects.test.ts index f3560ad9d..6c729f6f3 100644 --- a/test/configure-projects.test.ts +++ b/test/configure-projects.test.ts @@ -1,4 +1,5 @@ -import { deepEqual, equal, fail, ok, throws } from "node:assert/strict"; +import { XMLParser } from "fast-xml-parser"; +import { deepEqual, equal, ok, throws } from "node:assert/strict"; import * as nodefs from "node:fs"; import * as path from "node:path"; import { describe, it } from "node:test"; @@ -7,9 +8,24 @@ import { internalForTestingPurposesOnly, } from "../scripts/configure-projects.js"; -// This value needs to be the same as `package` in -// `android/app/src/main/AndroidManifest.xml` -const packageName = "com.microsoft.reacttestapp"; +const getAndroidPackageNameFromManifest = (() => { + let packageName = ""; + return () => { + if (!packageName) { + const androidManifestXml = nodefs.readFileSync( + "android/app/src/main/AndroidManifest.xml", + { encoding: "utf-8" } + ); + + const xml = new XMLParser({ ignoreAttributes: false }); + const { manifest } = xml.parse(androidManifestXml); + + packageName = manifest["@_package"]; + } + + return packageName; + }; +})(); describe("configureProjects()", () => { const manifestPath = path.join( @@ -33,7 +49,7 @@ describe("configureProjects()", () => { android: { sourceDir, manifestPath, - packageName, + packageName: getAndroidPackageNameFromManifest(), }, }); }); @@ -117,49 +133,7 @@ describe("findReactNativeConfig()", () => { describe("getAndroidPackageName()", () => { const { getAndroidPackageName } = internalForTestingPurposesOnly; - function mockfs(cliPlatformAndroidVersion: string): typeof nodefs { - const appManifest = "app.json"; - const cliPlatformAndroidPackageManifest = - /@react-native-community[/\\]cli-platform-android[/\\]package.json$/; - return { - ...nodefs, - existsSync: (p) => p === appManifest, - // @ts-expect-error Type 'string' is not assignable to type 'Buffer' - readFileSync: (p) => { - if (p === appManifest) { - return JSON.stringify({ android: { package: "com.testapp" } }); - } else if ( - typeof p === "string" && - cliPlatformAndroidPackageManifest.test(p) - ) { - return JSON.stringify({ - name: "@react-native-community/cli-platform-android", - version: cliPlatformAndroidVersion, - }); - } - - fail(`Unexpected file read: ${p}`); - }, - }; - } - - it("returns early if `@react-native-community/cli-platform-android` <12.3.7", () => { - equal(getAndroidPackageName(mockfs("11.4.1")), undefined); - equal(getAndroidPackageName(mockfs("12.3.6")), undefined); - }); - - it("returns package name if `@react-native-community/cli-platform-android` >=12.3.7 <13.0.0", () => { - equal(getAndroidPackageName(mockfs("12.3.7")), packageName); - equal(getAndroidPackageName(mockfs("12.999.999")), packageName); - }); - - it("returns early if `@react-native-community/cli-platform-android` <13.6.9", () => { - equal(getAndroidPackageName(mockfs("13.0.0")), undefined); - equal(getAndroidPackageName(mockfs("13.6.8")), undefined); - }); - - it("returns package name `@react-native-community/cli-platform-android` >=13.6.9", () => { - equal(getAndroidPackageName(mockfs("13.6.9")), packageName); - equal(getAndroidPackageName(mockfs("14.0.0")), packageName); + it("returns package name set in 'AndroidManifest.xml'", () => { + equal(getAndroidPackageNameFromManifest(), getAndroidPackageName()); }); }); diff --git a/test/configure/gatherConfig.test.ts b/test/configure/gatherConfig.test.ts index d9ebba624..505deec06 100644 --- a/test/configure/gatherConfig.test.ts +++ b/test/configure/gatherConfig.test.ts @@ -1,7 +1,6 @@ import { deepEqual } from "node:assert/strict"; import { describe, it } from "node:test"; import { gatherConfig as gatherConfigActual } from "../../scripts/configure.mjs"; -import { readTextFile } from "../../scripts/helpers.js"; import { join } from "../../scripts/template.mjs"; import type { Configuration, ConfigureParams } from "../../scripts/types.ts"; import { templatePath } from "../template.ts"; @@ -35,10 +34,6 @@ describe("gatherConfig()", () => { return config; } - const gradleWrapper = readTextFile( - "example/android/gradle/wrapper/gradle-wrapper.properties" - ).replaceAll("\r", ""); - it("returns configuration for all platforms", () => { deepEqual(gatherConfig(mockParams()), { dependencies: { @@ -76,26 +71,6 @@ describe("gatherConfig()", () => { " }", " }", "}", - "", - "allprojects {", - " repositories {", - " {", - " def searchDir = rootDir.toPath()", - " do {", - ' def p = searchDir.resolve("node_modules/react-native/android")', - " if (p.toFile().exists()) {", - " maven {", - " url = p.toRealPath().toString()", - " }", - " break", - " }", - " } while (searchDir = searchDir.getParent())", - " // As of 0.80, React Native is no longer installed from npm", - " }()", - " mavenCentral()", - " google()", - " }", - "}", "" ), "android/gradle.properties": join( @@ -156,7 +131,9 @@ describe("gatherConfig()", () => { "android/gradle/wrapper/gradle-wrapper.jar": { source: "example/android/gradle/wrapper/gradle-wrapper.jar", }, - "android/gradle/wrapper/gradle-wrapper.properties": gradleWrapper, + "android/gradle/wrapper/gradle-wrapper.properties": { + source: "example/android/gradle/wrapper/gradle-wrapper.properties", + }, "android/gradlew": { source: "example/android/gradlew", }, @@ -263,16 +240,15 @@ describe("gatherConfig()", () => { scripts: { android: "react-native run-android", "build:android": - "npm run mkdist && react-native bundle --entry-file index.js --platform android --dev true --bundle-output dist/main.android.jsbundle --assets-dest dist/res", + "react-native bundle --entry-file index.js --platform android --dev true --bundle-output dist/main.android.jsbundle --assets-dest dist/res", "build:ios": - "npm run mkdist && react-native bundle --entry-file index.js --platform ios --dev true --bundle-output dist/main.ios.jsbundle --assets-dest dist", + "react-native bundle --entry-file index.js --platform ios --dev true --bundle-output dist/main.ios.jsbundle --assets-dest dist", "build:macos": - "npm run mkdist && react-native bundle --entry-file index.js --platform macos --dev true --bundle-output dist/main.macos.jsbundle --assets-dest dist", + "react-native bundle --entry-file index.js --platform macos --dev true --bundle-output dist/main.macos.jsbundle --assets-dest dist", "build:windows": - "npm run mkdist && react-native bundle --entry-file index.js --platform windows --dev true --bundle-output dist/main.windows.bundle --assets-dest dist", + "react-native bundle --entry-file index.js --platform windows --dev true --bundle-output dist/main.windows.bundle --assets-dest dist", ios: "react-native run-ios", macos: "react-native run-macos --scheme Test", - mkdist: `node -e "require('node:fs').mkdirSync('dist', { recursive: true, mode: 0o755 })"`, start: "react-native start", windows: "react-native run-windows", }, @@ -363,7 +339,6 @@ describe("gatherConfig()", () => { }, oldFiles: [], scripts: { - mkdist: `node -e "require('node:fs').mkdirSync('dist', { recursive: true, mode: 0o755 })"`, start: "react-native start", }, }); @@ -433,9 +408,8 @@ describe("gatherConfig()", () => { ], scripts: { "build:ios": - "npm run mkdist && react-native bundle --entry-file index.js --platform ios --dev true --bundle-output dist/main.ios.jsbundle --assets-dest dist", + "react-native bundle --entry-file index.js --platform ios --dev true --bundle-output dist/main.ios.jsbundle --assets-dest dist", ios: "react-native run-ios", - mkdist: `node -e "require('node:fs').mkdirSync('dist', { recursive: true, mode: 0o755 })"`, start: "react-native start", }, }); @@ -476,26 +450,6 @@ describe("gatherConfig()", () => { " }", " }", "}", - "", - "allprojects {", - " repositories {", - " {", - " def searchDir = rootDir.toPath()", - " do {", - ' def p = searchDir.resolve("node_modules/react-native/android")', - " if (p.toFile().exists()) {", - " maven {", - " url = p.toRealPath().toString()", - " }", - " break", - " }", - " } while (searchDir = searchDir.getParent())", - " // As of 0.80, React Native is no longer installed from npm", - " }()", - " mavenCentral()", - " google()", - " }", - "}", "" ), "android/gradle.properties": join( @@ -556,7 +510,9 @@ describe("gatherConfig()", () => { "android/gradle/wrapper/gradle-wrapper.jar": { source: "example/android/gradle/wrapper/gradle-wrapper.jar", }, - "android/gradle/wrapper/gradle-wrapper.properties": gradleWrapper, + "android/gradle/wrapper/gradle-wrapper.properties": { + source: "example/android/gradle/wrapper/gradle-wrapper.properties", + }, "android/gradlew": { source: "example/android/gradlew", }, @@ -641,11 +597,10 @@ describe("gatherConfig()", () => { scripts: { android: "react-native run-android", "build:android": - "npm run mkdist && react-native bundle --entry-file index.js --platform android --dev true --bundle-output dist/main.android.jsbundle --assets-dest dist/res", + "react-native bundle --entry-file index.js --platform android --dev true --bundle-output dist/main.android.jsbundle --assets-dest dist/res", "build:ios": - "npm run mkdist && react-native bundle --entry-file index.js --platform ios --dev true --bundle-output dist/main.ios.jsbundle --assets-dest dist", + "react-native bundle --entry-file index.js --platform ios --dev true --bundle-output dist/main.ios.jsbundle --assets-dest dist", ios: "react-native run-ios", - mkdist: `node -e "require('node:fs').mkdirSync('dist', { recursive: true, mode: 0o755 })"`, start: "react-native start", }, }); diff --git a/test/configure/getConfig.test.ts b/test/configure/getConfig.test.ts index 783a59e77..d78adc47e 100644 --- a/test/configure/getConfig.test.ts +++ b/test/configure/getConfig.test.ts @@ -36,7 +36,7 @@ describe("getConfig()", () => { "react-native.config.js", ]); deepEqual(config.oldFiles, []); - deepEqual(Object.keys(config.scripts).sort(), ["mkdist", "start"]); + deepEqual(Object.keys(config.scripts).sort(), ["start"]); deepEqual(getDependencies("common", params), []); }); @@ -59,7 +59,7 @@ describe("getConfig()", () => { "tsconfig.json", ]); deepEqual(config.oldFiles, []); - deepEqual(Object.keys(config.scripts).sort(), ["mkdist", "start"]); + deepEqual(Object.keys(config.scripts).sort(), ["start"]); deepEqual(getDependencies("common", params), []); }); diff --git a/test/configure/getPlatformPackage.test.ts b/test/configure/getPlatformPackage.test.ts index dbe21fbc9..04229ecd3 100644 --- a/test/configure/getPlatformPackage.test.ts +++ b/test/configure/getPlatformPackage.test.ts @@ -13,9 +13,9 @@ describe("getPlatformPackage()", () => { deepEqual(pkg, { [name]: "^0.0.0" }); } - for (const targetVersion of ["0.73", "0.73.2", "^0.73", "^0.73.2"]) { + for (const targetVersion of ["0.78", "0.78.6", "^0.78", "^0.78.6"]) { const pkg = getPlatformPackage("macos", targetVersion); - deepEqual(pkg, { [name]: "^0.73.0" }); + deepEqual(pkg, { [name]: "^0.78.0" }); } equal(warnMock.mock.calls.length, 0); @@ -24,7 +24,7 @@ describe("getPlatformPackage()", () => { it("returns `undefined` when target version is outside range", (t) => { const warnMock = t.mock.method(console, "warn", () => null); - const versions = ["0.59", "9999.0"]; + const versions = ["0.75", "9999.0"]; for (const targetVersion of versions) { const pkg = getPlatformPackage("macos", targetVersion); equal(pkg, undefined); diff --git a/test/ios/app.test.ts b/test/ios/app.test.ts index 2bf391ba0..7b7cce022 100644 --- a/test/ios/app.test.ts +++ b/test/ios/app.test.ts @@ -231,17 +231,6 @@ describe("generateProject()", macosOnly, () => { deepEqual(trimPaths(result, cwd), PROJECT_FILES.customReactNative); }); - - it("finds community autolinking script for older versions", () => { - setMockFiles(makeMockProject(undefined, "0.74.0")); - - const result = generateProject("ios", "ios", {}); - - equal( - result.communityAutolinkingScriptPath, - "node_modules/@react-native-community/cli-platform-ios/native_modules.rb" - ); - }); }); const PROJECT_FILES = { @@ -260,7 +249,6 @@ const PROJECT_FILES = { PRODUCT_VERSION: "1.0", USER_HEADER_SEARCH_PATHS: ["/~/node_modules/.generated"], }, - communityAutolinkingScriptPath: undefined, reactNativeHostPath: "../node_modules/@rnx-kit/react-native-host", reactNativePath: "/~/node_modules/react-native-macos", reactNativeVersion: 1000000000, @@ -289,7 +277,6 @@ const PROJECT_FILES = { PRODUCT_VERSION: "1.0", USER_HEADER_SEARCH_PATHS: ["/~/node_modules/.generated"], }, - communityAutolinkingScriptPath: undefined, reactNativeHostPath: "../node_modules/@rnx-kit/react-native-host", reactNativePath: "/~/node_modules/react-native", reactNativeVersion: 1000000000, @@ -354,7 +341,6 @@ const PROJECT_FILES = { PRODUCT_VERSION: "1.0", USER_HEADER_SEARCH_PATHS: ["/~/node_modules/.generated"], }, - communityAutolinkingScriptPath: undefined, reactNativeHostPath: "../node_modules/@rnx-kit/react-native-host", reactNativePath: "/~/node_modules/react-native-macos", reactNativeVersion: 1000000000, @@ -420,7 +406,6 @@ const PROJECT_FILES = { PRODUCT_VERSION: "1.0", USER_HEADER_SEARCH_PATHS: ["/~/node_modules/.generated"], }, - communityAutolinkingScriptPath: undefined, reactNativeHostPath: "../node_modules/@rnx-kit/react-native-host", reactNativePath: "/~/node_modules/@callstack/react-native-visionos", reactNativeVersion: 1000000000, @@ -482,7 +467,6 @@ const PROJECT_FILES = { PRODUCT_VERSION: "1.0", USER_HEADER_SEARCH_PATHS: ["/~/node_modules/.generated"], }, - communityAutolinkingScriptPath: undefined, reactNativeHostPath: "../node_modules/@rnx-kit/react-native-host", reactNativePath: "/~/node_modules/react-native", reactNativeVersion: 81000, @@ -541,7 +525,6 @@ const PROJECT_FILES = { PRODUCT_VERSION: "1.0", USER_HEADER_SEARCH_PATHS: ["/~/node_modules/.generated"], }, - communityAutolinkingScriptPath: undefined, reactNativeHostPath: "../node_modules/@rnx-kit/react-native-host", reactNativePath: "/~/node_modules/react-native-macos", reactNativeVersion: 81000, @@ -601,7 +584,6 @@ const PROJECT_FILES = { PRODUCT_VERSION: "1.0", USER_HEADER_SEARCH_PATHS: ["/~/node_modules/.generated"], }, - communityAutolinkingScriptPath: undefined, reactNativeHostPath: "../node_modules/@rnx-kit/react-native-host", reactNativePath: "/~/node_modules/@callstack/react-native-visionos", reactNativeVersion: 81000, diff --git a/test/ios/features.test.ts b/test/ios/features.test.ts index 11b3440b1..a97db2141 100644 --- a/test/ios/features.test.ts +++ b/test/ios/features.test.ts @@ -1,4 +1,4 @@ -import { equal, ok } from "node:assert/strict"; +import { ok } from "node:assert/strict"; import { afterEach, before, describe, it } from "node:test"; import { isBridgelessEnabled, @@ -80,43 +80,31 @@ describe("isHermesEnabled()", () => { for (const platform of ["ios", "macos", "visionos"] as const) { it(`[${platform}] is disabled by default`, () => { - ok(!isHermesEnabled(platform, v(0, 79, 0), {})); + ok(!isHermesEnabled(v(0, 79, 0), {})); }); it(`[${platform}] returns true when enabled`, () => { - ok(isHermesEnabled(platform, v(0, 79, 0), { hermesEnabled: true })); + ok(isHermesEnabled(v(0, 79, 0), { hermesEnabled: true })); }); it(`[${platform}] returns true if 'USE_HERMES=1'`, () => { process.env["USE_HERMES"] = "1"; - ok(isHermesEnabled(platform, v(0, 79, 0), {})); + ok(isHermesEnabled(v(0, 79, 0), {})); }); it(`[${platform}] returns false if 'USE_HERMES=0'`, () => { process.env["USE_HERMES"] = "0"; - ok(!isHermesEnabled(platform, v(0, 79, 0), { hermesEnabled: true })); + ok(!isHermesEnabled(v(0, 79, 0), { hermesEnabled: true })); }); it(`[${platform}] always returns true from 0.80 on`, () => { - ok(isHermesEnabled(platform, v(0, 80, 0), {})); + ok(isHermesEnabled(v(0, 80, 0), {})); process.env["USE_HERMES"] = "0"; - ok(isHermesEnabled(platform, v(0, 80, 0), {})); + ok(isHermesEnabled(v(0, 80, 0), {})); }); } - - it("[visionos] builds from source when necessary", () => { - const options = { hermesEnabled: true }; - - equal(isHermesEnabled("visionos", v(0, 75, 0), options), "from-source"); - equal(isHermesEnabled("visionos", v(0, 76, 0), options), true); - - process.env["USE_HERMES"] = "1"; - - equal(isHermesEnabled("visionos", v(0, 75, 0), {}), "from-source"); - equal(isHermesEnabled("visionos", v(0, 76, 0), {}), true); - }); }); describe("isNewArchEnabled()", () => { @@ -137,9 +125,6 @@ describe("isNewArchEnabled()", () => { it("returns true if New Architecture is available and enabled", () => { ok(!isNewArchEnabled(0, {})); ok(!isNewArchEnabled(firstAvailableVersion, {})); - - // New architecture is first publicly available in 0.68, but we'll require 0.71 - ok(!isNewArchEnabled(v(0, 70, 999), { fabricEnabled: true })); ok(isNewArchEnabled(firstAvailableVersion, { fabricEnabled: true })); ok(isNewArchEnabled(firstAvailableVersion, { newArchEnabled: true })); }); @@ -147,14 +132,12 @@ describe("isNewArchEnabled()", () => { it("returns true if `RCT_NEW_ARCH_ENABLED=1`", () => { process.env["RCT_NEW_ARCH_ENABLED"] = "1"; - ok(!isNewArchEnabled(v(0, 70, 999), {})); ok(isNewArchEnabled(firstAvailableVersion, {})); }); it("returns false if `RCT_NEW_ARCH_ENABLED=0`", () => { process.env["RCT_NEW_ARCH_ENABLED"] = "0"; - ok(!isNewArchEnabled(v(0, 70, 999), {})); ok(!isNewArchEnabled(firstAvailableVersion, {})); ok(!isNewArchEnabled(firstAvailableVersion, { fabric_enabled: true })); }); diff --git a/test/ios/xcode.test.ts b/test/ios/xcode.test.ts index 246afc232..f9c55cd93 100644 --- a/test/ios/xcode.test.ts +++ b/test/ios/xcode.test.ts @@ -27,7 +27,7 @@ import { PRODUCT_BUNDLE_IDENTIFIER, USER_HEADER_SEARCH_PATHS, } from "../../ios/xcode.mjs"; -import { readTextFile, v } from "../../scripts/helpers.js"; +import { readTextFile } from "../../scripts/helpers.js"; import type { ApplePlatform, JSONObject, @@ -248,32 +248,6 @@ describe("applyPreprocessorDefinitions()", () => { "REACT_NATIVE_VERSION=0", ]); }); - - it("applies C++17 workarounds for unpatched versions", () => { - const versions = [ - [v(0, 71, 0), true], - [v(0, 71, 3), true], - [v(0, 71, 4), false], - [v(0, 72, 0), true], - [v(0, 72, 4), true], - [v(0, 72, 5), false], - ] as const; - - for (const [version, enable] of versions) { - const project = makeProjectConfiguration(); - const { buildSettings } = project; - - project.reactNativeVersion = version; - applyPreprocessorDefinitions(project); - - const expected = [`REACT_NATIVE_VERSION=${version}`]; - if (enable) { - expected.push("_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION=1"); - } - - deepEqual(buildSettings[GCC_PREPROCESSOR_DEFINITIONS], expected); - } - }); }); describe("applySwiftFlags()", () => { diff --git a/test/pack.test.ts b/test/pack.test.ts index b942712a4..1f39af77c 100644 --- a/test/pack.test.ts +++ b/test/pack.test.ts @@ -37,10 +37,7 @@ describe("npm pack", () => { "android/app/lint.xml", "android/app/src/camera/java/com/microsoft/reacttestapp/camera/MainActivityExtensions.kt", "android/app/src/camera/java/com/microsoft/reacttestapp/camera/QRCodeScannerFragment.kt", - "android/app/src/devserverhelper-0.73/java/com/microsoft/reacttestapp/react/DevServerHelperCompat.kt", - "android/app/src/devserverhelper-0.74/java/com/microsoft/reacttestapp/react/DevServerHelperCompat.kt", "android/app/src/devserverhelper-0.75/java/com/microsoft/reacttestapp/react/DevServerHelperCompat.kt", - "android/app/src/devserverhelper-pre-0.73/java/com/microsoft/reacttestapp/react/DevServerHelperCompat.kt", "android/app/src/main/AndroidManifest.xml", "android/app/src/main/java/com/microsoft/reacttestapp/MainActivity.kt", "android/app/src/main/java/com/microsoft/reacttestapp/Session.kt", @@ -89,20 +86,11 @@ describe("npm pack", () => { "android/app/src/new-arch-0.81/java/com/microsoft/reacttestapp/compat/ReactNativeHostCompat.kt", "android/app/src/new-arch-0.81/java/com/microsoft/reacttestapp/fabric/ComponentsRegistry.kt", "android/app/src/new-arch-0.81/java/com/microsoft/reacttestapp/turbomodule/TurboModuleManagerDelegate.kt", - "android/app/src/new-arch/java/com/microsoft/reacttestapp/compat/ReactNativeHostCompat.kt", - "android/app/src/new-arch/java/com/microsoft/reacttestapp/fabric/ComponentsRegistry.kt", - "android/app/src/new-arch/java/com/microsoft/reacttestapp/turbomodule/TurboModuleManagerDelegate.kt", "android/app/src/no-camera/java/com/microsoft/reacttestapp/camera/MainActivityExtensions.kt", "android/app/src/old-arch/java/com/microsoft/reacttestapp/compat/ReactNativeHostCompat.kt", - "android/app/src/reactactivitydelegate-0.72/java/com/microsoft/reacttestapp/component/ComponentActivityDelegate.kt", - "android/app/src/reactactivitydelegate-0.74/java/com/microsoft/reacttestapp/component/ComponentActivityDelegate.kt", "android/app/src/reactactivitydelegate-0.75/java/com/microsoft/reacttestapp/component/ComponentActivityDelegate.kt", - "android/app/src/reactactivitydelegate-pre-0.72/java/com/microsoft/reacttestapp/component/ComponentActivityDelegate.kt", - "android/app/src/reactapplication-0.73/java/com/microsoft/reacttestapp/TestApp.kt", "android/app/src/reactapplication-0.76/java/com/microsoft/reacttestapp/TestApp.kt", - "android/app/src/reactapplication-pre-0.73/java/com/microsoft/reacttestapp/TestApp.kt", "android/app/src/reacthost-0.76/java/com/microsoft/reacttetapp/react/MainReactNativeHost.kt", - "android/app/src/reacthost-legacy/java/com/microsoft/reacttetapp/react/MainReactNativeHost.kt", "android/autolink.gradle", "android/autolink.mjs", "android/config-plugins.gradle", @@ -166,7 +154,6 @@ describe("npm pack", () => { "ios/pod_helpers.rb", "ios/privacyManifest.mjs", "ios/test_app.rb", - "ios/use_react_native-0.70.rb", "ios/use_react_native-0.71.rb", "ios/utils.mjs", "ios/xcode.mjs", diff --git a/test/test_test_app.rb b/test/test_test_app.rb index 4d2da463c..04fe52ae1 100644 --- a/test/test_test_app.rb +++ b/test/test_test_app.rb @@ -23,7 +23,6 @@ def test_react_native_pods [0, '0.71'], [v(1000, 0, 0), '0.71'], [v(0, 71, 0), '0.71'], - [v(0, 70, 13), '0.70'], ].each do |target, profile| assert_equal("use_react_native-#{profile}", react_native_pods(target)) end diff --git a/windows/ExperimentalFeatures.props b/windows/ExperimentalFeatures.props index 26b727e29..e22ce48e6 100644 --- a/windows/ExperimentalFeatures.props +++ b/windows/ExperimentalFeatures.props @@ -10,7 +10,7 @@ false diff --git a/windows/app.mjs b/windows/app.mjs index 85d21096b..92d1f5e4c 100755 --- a/windows/app.mjs +++ b/windows/app.mjs @@ -9,7 +9,6 @@ import { isMain, readTextFile, requireTransitive, - v, writeTextFile, } from "../scripts/helpers.js"; import * as colors from "../scripts/utils/colors.mjs"; @@ -256,7 +255,7 @@ export async function generateSolution(destPath, options, fs = nodefs) { console.log(colors.cyan(colors.bold("info")), `'${props}' already exists`); } else { const { msbuildprops, useHermes } = options; - const { useExperimentalNuGet, useFabric, versionNumber } = info; + const { useExperimentalNuGet, useFabric } = info; const url = new URL(experimentalFeaturesPropsFilename, import.meta.url); await copyAndReplaceAsync( fileURLToPath(url), @@ -264,7 +263,7 @@ export async function generateSolution(destPath, options, fs = nodefs) { { "false": `${useFabric}`, "false": `${useFabric}`, - "true": `${useHermes == null ? versionNumber >= v(0, 73, 0) : useHermes}`, + "true": `${useHermes !== false}`, "false": `${useFabric}`, "false": `${useExperimentalNuGet}`, "": msbuildprops ?? "", @@ -355,12 +354,12 @@ if (isMain(import.meta.url)) { type: "string", }, "use-fabric": { - description: "Use New Architecture [experimental] (supported on 0.73+)", + description: "Use New Architecture [experimental]", type: "boolean", }, "use-hermes": { description: - "Use Hermes instead of Chakra as the JS engine (enabled by default on 0.73+)", + "Use Hermes instead of Chakra as the JS engine (enabled by default)", type: "boolean", }, "use-nuget": { diff --git a/windows/project.mjs b/windows/project.mjs index d1ab54f5f..c2931b9b5 100644 --- a/windows/project.mjs +++ b/windows/project.mjs @@ -12,7 +12,6 @@ import { readJSONFile, readTextFile, toVersionNumber, - v, } from "../scripts/helpers.js"; import * as colors from "../scripts/utils/colors.mjs"; @@ -414,12 +413,7 @@ export async function projectInfo( ) { const version = getPackageVersion("react-native-windows", rnWindowsPath, fs); const versionNumber = toVersionNumber(version); - - const newArch = - Boolean(useFabric) && (versionNumber === 0 || versionNumber >= v(0, 74, 0)); - if (useFabric && !newArch) { - warn("New Architecture requires `react-native-windows` 0.74+"); - } + const newArch = Boolean(useFabric); return { version, diff --git a/yarn.lock b/yarn.lock index e73bb5bae..feed43100 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12499,12 +12499,12 @@ __metadata: typescript: "npm:^5.0.0" uuid: "npm:^11.0.0" peerDependencies: - "@callstack/react-native-visionos": 0.73 - 0.79 + "@callstack/react-native-visionos": 0.76 - 0.79 "@expo/config-plugins": ">=5.0" - react: 18.1 - 19.1 - react-native: 0.70 - 0.82 || >=0.83.0-0 <0.83.0 - react-native-macos: ^0.0.0-0 || 0.71 - 0.79 - react-native-windows: ^0.0.0-0 || 0.70 - 0.79 + react: 18.2 - 19.1 + react-native: 0.76 - 0.82 || >=0.83.0-0 <0.83.0 + react-native-macos: ^0.0.0-0 || 0.76 - 0.79 + react-native-windows: ^0.0.0-0 || 0.76 - 0.79 peerDependenciesMeta: "@callstack/react-native-visionos": optional: true