Move Flipper integration to a separate Gradle module inside ReactAndroid (#37688)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/37688

This moves the `ReactNativeFlipper` classes used to configure Flipper on Android from the template to
a separate Gradle artifact that will be published under the coordinates:
```
com.facebook.react:flipper-integration:0.73.x
```

This reduces the footprint of Flipper on the app template and makes easier for user on 0.73 to migrate
to Kotlin (as they will now have to migrate only 2 files rather than 4).

Changelog:
[Android] [Changed] - Move Flipper integration to a separate Gradle module inside `ReactAndroid`

Reviewed By: huntie

Differential Revision: D46441588

fbshipit-source-id: e197f29b7386b52091b8d38ed09bbd8f74a997df
This commit is contained in:
Nicola Corti 2023-07-04 06:01:09 -07:00 committed by Facebook GitHub Bot
parent 0e80fdb1e9
commit 16201f8be3
19 changed files with 101 additions and 115 deletions

1
.gitignore vendored
View File

@ -39,6 +39,7 @@ project.xcworkspace
/packages/react-native/ReactAndroid/gradlew.bat
/packages/react-native/ReactAndroid/external-artifacts/build/
/packages/react-native/ReactAndroid/external-artifacts/artifacts/
/packages/react-native/ReactAndroid/flipper-integration/build/
/packages/react-native/ReactAndroid/hermes-engine/build/
/packages/react-native/ReactAndroid/hermes-engine/.cxx/
/packages/react-native/template/android/app/build/

View File

@ -99,6 +99,8 @@ tasks.register("publishAllToMavenTempLocal") {
description = "Publish all the artifacts to be available inside a Maven Local repository on /tmp."
dependsOn(":packages:react-native:ReactAndroid:publishAllPublicationsToMavenTempLocalRepository")
// We don't publish the external-artifacts to Maven Local as CircleCI is using it via workspace.
dependsOn(
":packages:react-native:ReactAndroid:flipper-integration:publishAllPublicationsToMavenTempLocalRepository")
dependsOn(
":packages:react-native:ReactAndroid:hermes-engine:publishAllPublicationsToMavenTempLocalRepository")
}
@ -107,5 +109,6 @@ tasks.register("publishAllToSonatype") {
description = "Publish all the artifacts to Sonatype (Maven Central or Snapshot repository)"
dependsOn(":packages:react-native:ReactAndroid:publishToSonatype")
dependsOn(":packages:react-native:ReactAndroid:external-artifacts:publishToSonatype")
dependsOn(":packages:react-native:ReactAndroid:flipper-integration:publishToSonatype")
dependsOn(":packages:react-native:ReactAndroid:hermes-engine:publishToSonatype")
}

View File

@ -45,7 +45,8 @@ internal object DependencyUtils {
/**
* This method takes care of configuring the resolution strategy for both the app and all the 3rd
* party libraries which are auto-linked. Specifically it takes care of:
* - Forcing the react-android/hermes-android version to the one specified in the package.json
* - Forcing the react-android/hermes-android/flipper-integration version to the one specified in
* the package.json
* - Substituting `react-native` with `react-android` and `hermes-engine` with `hermes-android`.
*/
fun configureDependencies(
@ -68,6 +69,7 @@ internal object DependencyUtils {
configuration.resolutionStrategy.force(
"${groupString}:react-android:${versionString}",
"${groupString}:hermes-android:${versionString}",
"${groupString}:flipper-integration:${versionString}",
)
}
}

View File

@ -78,7 +78,7 @@ internal object NdkConfiguratorUtils {
) {
if (!project.isNewArchEnabled) {
// For Old Arch, we set a pickFirst only on libraries that we know are
// clashing with our direct dependencies (FBJNI, Flipper and Hermes).
// clashing with our direct dependencies (mainly FBJNI and Hermes).
variant.packaging.jniLibs.pickFirsts.addAll(
listOf(
"**/libfbjni.so",

View File

@ -0,0 +1,2 @@
# Make sure we never publish the build folders to npm.
build/

View File

@ -0,0 +1,61 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
plugins {
id("com.android.library")
id("maven-publish")
id("signing")
id("org.jetbrains.kotlin.android")
}
group = "com.facebook.react"
version = parent.publishing_version
repositories {
// Normally RNGP will set repositories for all modules,
// but when consumed from source, we need to re-declare
// those repositories as there is no app module there.
mavenCentral()
google()
}
android {
compileSdk 33
buildToolsVersion = "33.0.0"
namespace "com.facebook.react.flipper"
defaultConfig {
minSdk = 21
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
kotlin {
jvmToolchain(11)
}
dependencies {
implementation project(':packages:react-native:ReactAndroid')
debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}")
debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") {
exclude group:'com.squareup.okhttp3', module:'okhttp'
}
debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}")
}
publishing {
multipleVariants {
withSourcesJar()
allVariants()
}
}
}
apply from: "../publish.gradle"

View File

@ -0,0 +1,2 @@
# Version of flipper SDK to use for this integration
FLIPPER_VERSION=0.182.0

View File

@ -1,4 +1,11 @@
package com.helloworld
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.flipper
import android.content.Context
import com.facebook.flipper.android.AndroidFlipperClient
@ -21,6 +28,7 @@ import com.facebook.react.modules.network.NetworkingModule
* flavor of it. Here you can add your own plugins and customize the Flipper setup.
*/
object ReactNativeFlipper {
@JvmStatic
fun initializeFlipper(context: Context, reactInstanceManager: ReactInstanceManager) {
if (FlipperUtils.shouldEnableFlipper(context)) {
val client = AndroidFlipperClient.getInstance(context)

View File

@ -1,4 +1,11 @@
package com.helloworld
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.flipper
import android.content.Context
import com.facebook.react.ReactInstanceManager
@ -9,6 +16,7 @@ import com.facebook.react.ReactInstanceManager
*/
object ReactNativeFlipper {
@Suppress("UNUSED_PARAMETER")
@JvmStatic
fun initializeFlipper(context: Context, reactInstanceManager: ReactInstanceManager) {
// Do nothing as we don't want to initialize Flipper on Release.
}

View File

@ -29,3 +29,8 @@ include(":packages:react-native:ReactAndroid:hermes-engine")
project(":packages:react-native:ReactAndroid:hermes-engine").projectDir =
file("ReactAndroid/hermes-engine/")
include(":packages:react-native:ReactAndroid:flipper-integration")
project(":packages:react-native:ReactAndroid:flipper-integration").projectDir =
file("ReactAndroid/flipper-integration/")

View File

@ -107,13 +107,8 @@ android {
dependencies {
// The version of react-native is set by the React Native Gradle Plugin
implementation("com.facebook.react:react-android")
implementation("com.facebook.react:flipper-integration")
debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}")
debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") {
exclude group:'com.squareup.okhttp3', module:'okhttp'
}
debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}")
if (hermesEnabled.toBoolean()) {
implementation("com.facebook.react:hermes-android")
} else {

View File

@ -7,6 +7,7 @@ import com.facebook.react.ReactNativeHost
import com.facebook.react.ReactPackage
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load
import com.facebook.react.defaults.DefaultReactNativeHost
import com.facebook.react.flipper.ReactNativeFlipper
import com.facebook.soloader.SoLoader
class MainApplication : Application(), ReactApplication {

View File

@ -24,9 +24,6 @@ android.useAndroidX=true
# Automatically convert third-party libraries to use AndroidX
android.enableJetifier=true
# Version of flipper SDK to use with React Native
FLIPPER_VERSION=0.182.0
# Use this property to specify which architecture you want to build.
# You can also override it from the CLI using
# ./gradlew <task> -PreactNativeArchitectures=x86_64

View File

@ -156,14 +156,11 @@ android {
dependencies {
// Build React Native from source
implementation project(':packages:react-native:ReactAndroid')
implementation project(':packages:react-native:ReactAndroid:flipper-integration')
// Consume Hermes as built from source only for the Hermes variant.
hermesImplementation(project(":packages:react-native:ReactAndroid:hermes-engine"))
debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}")
debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}")
debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}")
jscImplementation jscFlavor
androidTestImplementation 'junit:junit:4.12'

View File

@ -4,9 +4,6 @@ org.gradle.parallel=true
android.useAndroidX=true
android.enableJetifier=true
# Version of flipper SDK to use with React Native
FLIPPER_VERSION=0.182.0
# RN-Tester is building with NewArch always enabled
newArchEnabled=true
# RN-Tester is running with Hermes enabled and filtering variants with enableHermesOnlyInVariants

View File

@ -1,74 +0,0 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.uiapp;
import android.content.Context;
import com.facebook.flipper.android.AndroidFlipperClient;
import com.facebook.flipper.android.utils.FlipperUtils;
import com.facebook.flipper.core.FlipperClient;
import com.facebook.flipper.plugins.crashreporter.CrashReporterPlugin;
import com.facebook.flipper.plugins.databases.DatabasesFlipperPlugin;
import com.facebook.flipper.plugins.fresco.FrescoFlipperPlugin;
import com.facebook.flipper.plugins.inspector.DescriptorMapping;
import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin;
import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor;
import com.facebook.flipper.plugins.network.NetworkFlipperPlugin;
import com.facebook.flipper.plugins.react.ReactFlipperPlugin;
import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin;
import com.facebook.react.ReactInstanceEventListener;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.modules.network.NetworkingModule;
import okhttp3.OkHttpClient;
public class ReactNativeFlipper {
public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) {
if (FlipperUtils.shouldEnableFlipper(context)) {
final FlipperClient client = AndroidFlipperClient.getInstance(context);
client.addPlugin(new InspectorFlipperPlugin(context, DescriptorMapping.withDefaults()));
client.addPlugin(new ReactFlipperPlugin());
client.addPlugin(new DatabasesFlipperPlugin(context));
client.addPlugin(new SharedPreferencesFlipperPlugin(context));
client.addPlugin(CrashReporterPlugin.getInstance());
NetworkFlipperPlugin networkFlipperPlugin = new NetworkFlipperPlugin();
NetworkingModule.setCustomClientBuilder(
new NetworkingModule.CustomClientBuilder() {
@Override
public void apply(OkHttpClient.Builder builder) {
builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin));
}
});
client.addPlugin(networkFlipperPlugin);
client.start();
// Fresco Plugin needs to ensure that ImagePipelineFactory is initialized
// Hence we run if after all native modules have been initialized
ReactContext reactContext = reactInstanceManager.getCurrentReactContext();
if (reactContext == null) {
reactInstanceManager.addReactInstanceEventListener(
new ReactInstanceEventListener() {
@Override
public void onReactContextInitialized(ReactContext reactContext) {
reactInstanceManager.removeReactInstanceEventListener(this);
reactContext.runOnNativeModulesQueueThread(
new Runnable() {
@Override
public void run() {
client.addPlugin(new FrescoFlipperPlugin());
}
});
}
});
} else {
client.addPlugin(new FrescoFlipperPlugin());
}
}
}
}

View File

@ -26,6 +26,7 @@ import com.facebook.react.defaults.DefaultComponentsRegistry;
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
import com.facebook.react.defaults.DefaultReactNativeHost;
import com.facebook.react.fabric.ComponentFactory;
import com.facebook.react.flipper.ReactNativeFlipper;
import com.facebook.react.interfaces.ReactHostInterface;
import com.facebook.react.module.model.ReactModuleInfo;
import com.facebook.react.module.model.ReactModuleInfoProvider;

View File

@ -1,21 +0,0 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.uiapp;
import android.content.Context;
import com.facebook.react.ReactInstanceManager;
/**
* Class responsible of loading Flipper inside your React Native application. This is the release
* flavor of it so it's empty as we don't want to load Flipper.
*/
public class ReactNativeFlipper {
public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) {
// Do nothing as we don't want to initialize Flipper on Release.
}
}

View File

@ -15,6 +15,7 @@ pluginManagement {
include(
":packages:react-native:ReactAndroid",
":packages:react-native:ReactAndroid:flipper-integration",
":packages:react-native:ReactAndroid:hermes-engine",
":packages:react-native:ReactAndroid:external-artifacts")