From 5f3c5aa529ed75414eb339c3d8fd2c9628534621 Mon Sep 17 00:00:00 2001 From: Nicola Corti Date: Mon, 23 May 2022 07:58:41 -0700 Subject: [PATCH] Extend the React Native Gradle plugin to accept a config from package.json Summary: This extends the Gradle plugin to allow configuration for `codegenConfig` from the `package.json` that lives in one of the root folder. There are a couple of points open for discussion. The most important one is that now we're moving from absolute paths to relative paths, from the package.json location. I'm not entirely sure this will work correctly for users in monorepos, so we might consider this carefully. Moreover, I've moved the `codegenJavaPackageName` to be `android.javaPackageName`. Happy to discuss this further. Changelog: [Android] [Added] - Extend the React Native Gradle plugin to accept a config from package.json Reviewed By: cipolleschi Differential Revision: D36374475 fbshipit-source-id: fe669ebd5bc92abbbe57677c1995d0e01f2400d7 --- .../kotlin/com/facebook/react/ReactPlugin.kt | 33 +++++-- .../react/model/ModelCodegenConfig.kt | 15 +++ .../react/model/ModelCodegenConfigAndroid.kt | 10 ++ .../facebook/react/model/ModelPackageJson.kt | 10 ++ .../tasks/GenerateCodegenArtifactsTask.kt | 33 ++++++- .../react/tasks/GenerateCodegenSchemaTask.kt | 7 +- .../com/facebook/react/utils/JsonUtils.kt | 21 +++++ .../tasks/GenerateCodegenArtifactsTaskTest.kt | 84 ++++++++++++++++- .../com/facebook/react/utils/JsonUtilsTest.kt | 92 +++++++++++++++++++ packages/rn-tester/android/app/build.gradle | 6 +- .../android/app/src/main/jni/Android.mk | 4 +- .../main/jni/RNTesterAppModuleProvider.cpp | 4 +- .../main/jni/RNTesterComponentsRegistry.cpp | 2 +- packages/rn-tester/package.json | 5 +- 14 files changed, 298 insertions(+), 28 deletions(-) create mode 100644 packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/model/ModelCodegenConfig.kt create mode 100644 packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/model/ModelCodegenConfigAndroid.kt create mode 100644 packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/model/ModelPackageJson.kt create mode 100644 packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/JsonUtils.kt create mode 100644 packages/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/JsonUtilsTest.kt diff --git a/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/ReactPlugin.kt b/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/ReactPlugin.kt index c5ceebcdff5765..22628fa94e893e 100644 --- a/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/ReactPlugin.kt +++ b/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/ReactPlugin.kt @@ -14,6 +14,7 @@ import com.android.build.gradle.internal.tasks.factory.dependsOn import com.facebook.react.tasks.BuildCodegenCLITask import com.facebook.react.tasks.GenerateCodegenArtifactsTask import com.facebook.react.tasks.GenerateCodegenSchemaTask +import com.facebook.react.utils.JsonUtils import java.io.File import kotlin.system.exitProcess import org.gradle.api.Plugin @@ -67,10 +68,10 @@ class ReactPlugin : Plugin { /** * A plugin to enable react-native-codegen in Gradle environment. See the Gradle API docs for more - * information: https://docs.gradle.org/6.5.1/javadoc/org/gradle/api/Project.html + * information: https://docs.gradle.org/current/javadoc/org/gradle/api/Project.html */ private fun applyCodegenPlugin(project: Project, extension: ReactExtension) { - // 1. Set up build dir. + // First, we set up the output dir for the codegen. val generatedSrcDir = File(project.buildDir, "generated/source/codegen") val buildCodegenTask = @@ -80,18 +81,33 @@ class ReactPlugin : Plugin { it.bashWindowsHome.set(bashWindowsHome) } - // 2. Task: produce schema from JS files. + // We create the task to produce schema from JS files. val generateCodegenSchemaTask = project.tasks.register( - "generateCodegenSchemaFromJavaScript", GenerateCodegenSchemaTask::class.java) { + "generateCodegenSchemaFromJavaScript", GenerateCodegenSchemaTask::class.java) { it -> it.dependsOn(buildCodegenTask) - it.jsRootDir.set(extension.jsRootDir) it.nodeExecutableAndArgs.set(extension.nodeExecutableAndArgs) it.codegenDir.set(extension.codegenDir) it.generatedSrcDir.set(generatedSrcDir) + + // We're reading the package.json at configuration time to properly feed + // the `jsRootDir` @Input property of this task. Therefore, the + // parsePackageJson should be invoked here. + val parsedPackageJson = + extension.root.file("package.json").orNull?.asFile?.let { + JsonUtils.fromCodegenJson(it) + } + + val parsedJsRootDir = + parsedPackageJson?.codegenConfig?.jsSrcsDir?.let { relativePath -> + extension.root.dir(relativePath) + } + ?: extension.jsRootDir + + it.jsRootDir.set(parsedJsRootDir) } - // 3. Task: generate Java code from schema. + // We create the task to generate Java code from schema. val generateCodegenArtifactsTask = project.tasks.register( "generateCodegenArtifactsFromSchema", GenerateCodegenArtifactsTask::class.java) { @@ -100,12 +116,13 @@ class ReactPlugin : Plugin { it.deprecatedReactRoot.set(extension.reactRoot) it.nodeExecutableAndArgs.set(extension.nodeExecutableAndArgs) it.codegenDir.set(extension.codegenDir) + it.generatedSrcDir.set(generatedSrcDir) + it.packageJsonFile.set(extension.root.file("package.json")) it.codegenJavaPackageName.set(extension.codegenJavaPackageName) it.libraryName.set(extension.libraryName) - it.generatedSrcDir.set(generatedSrcDir) } - // 4. Add dependencies & generated sources to the project. + // We add dependencies & generated sources to the project. // Note: This last step needs to happen after the project has been evaluated. project.afterEvaluate { diff --git a/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/model/ModelCodegenConfig.kt b/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/model/ModelCodegenConfig.kt new file mode 100644 index 00000000000000..26d7f08d95d3c7 --- /dev/null +++ b/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/model/ModelCodegenConfig.kt @@ -0,0 +1,15 @@ +/* + * 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.model + +data class ModelCodegenConfig( + val name: String?, + val type: String?, + val jsSrcsDir: String?, + val android: ModelCodegenConfigAndroid? +) diff --git a/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/model/ModelCodegenConfigAndroid.kt b/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/model/ModelCodegenConfigAndroid.kt new file mode 100644 index 00000000000000..7619098a8dbc74 --- /dev/null +++ b/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/model/ModelCodegenConfigAndroid.kt @@ -0,0 +1,10 @@ +/* + * 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.model + +data class ModelCodegenConfigAndroid(val javaPackageName: String?) diff --git a/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/model/ModelPackageJson.kt b/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/model/ModelPackageJson.kt new file mode 100644 index 00000000000000..96e2bd22d704fb --- /dev/null +++ b/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/model/ModelPackageJson.kt @@ -0,0 +1,10 @@ +/* + * 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.model + +data class ModelPackageJson(val codegenConfig: ModelCodegenConfig?) diff --git a/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/tasks/GenerateCodegenArtifactsTask.kt b/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/tasks/GenerateCodegenArtifactsTask.kt index 40470979469ef6..f00bfad9143f46 100644 --- a/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/tasks/GenerateCodegenArtifactsTask.kt +++ b/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/tasks/GenerateCodegenArtifactsTask.kt @@ -7,14 +7,20 @@ package com.facebook.react.tasks +import com.facebook.react.utils.JsonUtils import com.facebook.react.utils.windowsAwareCommandLine import org.gradle.api.file.Directory import org.gradle.api.file.DirectoryProperty import org.gradle.api.file.RegularFile +import org.gradle.api.file.RegularFileProperty import org.gradle.api.provider.ListProperty import org.gradle.api.provider.Property import org.gradle.api.provider.Provider -import org.gradle.api.tasks.* +import org.gradle.api.tasks.Exec +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.InputFile +import org.gradle.api.tasks.Internal +import org.gradle.api.tasks.OutputDirectory abstract class GenerateCodegenArtifactsTask : Exec() { @@ -24,6 +30,8 @@ abstract class GenerateCodegenArtifactsTask : Exec() { @get:Internal abstract val generatedSrcDir: DirectoryProperty + @get:InputFile abstract val packageJsonFile: RegularFileProperty + @get:Input abstract val nodeExecutableAndArgs: ListProperty @get:Input abstract val codegenJavaPackageName: Property @@ -46,7 +54,9 @@ abstract class GenerateCodegenArtifactsTask : Exec() { override fun exec() { checkForDeprecatedProperty() - setupCommandLine() + + val (resolvedLibraryName, resolvedCodegenJavaPackageName) = resolveTaskParameters() + setupCommandLine(resolvedLibraryName, resolvedCodegenJavaPackageName) super.exec() } @@ -74,7 +84,20 @@ abstract class GenerateCodegenArtifactsTask : Exec() { } } - internal fun setupCommandLine() { + internal fun resolveTaskParameters(): Pair { + val parsedPackageJson = + if (packageJsonFile.isPresent && packageJsonFile.get().asFile.exists()) { + JsonUtils.fromCodegenJson(packageJsonFile.get().asFile) + } else { + null + } + val resolvedLibraryName = parsedPackageJson?.codegenConfig?.name ?: libraryName.get() + val resolvedCodegenJavaPackageName = + parsedPackageJson?.codegenConfig?.android?.javaPackageName ?: codegenJavaPackageName.get() + return resolvedLibraryName to resolvedCodegenJavaPackageName + } + + internal fun setupCommandLine(libraryName: String, codegenJavaPackageName: String) { commandLine( windowsAwareCommandLine( *nodeExecutableAndArgs.get().toTypedArray(), @@ -86,8 +109,8 @@ abstract class GenerateCodegenArtifactsTask : Exec() { "--outputDir", generatedSrcDir.get().asFile.absolutePath, "--libraryName", - libraryName.get(), + libraryName, "--javaPackageName", - codegenJavaPackageName.get())) + codegenJavaPackageName)) } } diff --git a/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/tasks/GenerateCodegenSchemaTask.kt b/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/tasks/GenerateCodegenSchemaTask.kt index 7d372f07904dec..e0c44599205255 100644 --- a/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/tasks/GenerateCodegenSchemaTask.kt +++ b/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/tasks/GenerateCodegenSchemaTask.kt @@ -29,7 +29,12 @@ abstract class GenerateCodegenSchemaTask : Exec() { @get:Input abstract val nodeExecutableAndArgs: ListProperty - @get:InputFiles val jsInputFiles = project.fileTree(jsRootDir) { it.include("**/*.js") } + @get:InputFiles + val jsInputFiles = + project.fileTree(jsRootDir) { + it.include("**/*.js") + it.exclude("**/generated/source/codegen/**/*") + } @get:OutputFile val generatedSchemaFile: Provider = generatedSrcDir.file("schema.json") diff --git a/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/JsonUtils.kt b/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/JsonUtils.kt new file mode 100644 index 00000000000000..4fa27510f484e1 --- /dev/null +++ b/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/JsonUtils.kt @@ -0,0 +1,21 @@ +/* + * 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.utils + +import com.facebook.react.model.ModelPackageJson +import com.google.gson.Gson +import java.io.File + +object JsonUtils { + private val gsonConverter = Gson() + + fun fromCodegenJson(input: File): ModelPackageJson? = + input.bufferedReader().use { + runCatching { gsonConverter.fromJson(it, ModelPackageJson::class.java) }.getOrNull() + } +} diff --git a/packages/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/tasks/GenerateCodegenArtifactsTaskTest.kt b/packages/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/tasks/GenerateCodegenArtifactsTaskTest.kt index 44e02fec6a9df1..a559b036422cdb 100644 --- a/packages/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/tasks/GenerateCodegenArtifactsTaskTest.kt +++ b/packages/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/tasks/GenerateCodegenArtifactsTaskTest.kt @@ -58,11 +58,14 @@ class GenerateCodegenArtifactsTaskTest { @Test fun generateCodegenSchema_simpleProperties_areInsideInput() { + val packageJsonFile = tempFolder.newFile("package.json") + val task = createTestTask { it.nodeExecutableAndArgs.set(listOf("npm", "help")) it.codegenJavaPackageName.set("com.example.test") it.libraryName.set("example-test") + it.packageJsonFile.set(packageJsonFile) } assertEquals(listOf("npm", "help"), task.nodeExecutableAndArgs.get()) @@ -75,7 +78,7 @@ class GenerateCodegenArtifactsTaskTest { @Test @WithOs(OS.UNIX) - fun setupCommandLine_withoutJavaGenerator_willSetupCorrectly() { + fun setupCommandLine_willSetupCorrectly() { val reactNativeDir = tempFolder.newFolder("node_modules/react-native/") val codegenDir = tempFolder.newFolder("codegen") val outputDir = tempFolder.newFolder("output") @@ -86,11 +89,9 @@ class GenerateCodegenArtifactsTaskTest { it.codegenDir.set(codegenDir) it.generatedSrcDir.set(outputDir) it.nodeExecutableAndArgs.set(listOf("--verbose")) - it.codegenJavaPackageName.set("com.example.test") - it.libraryName.set("example-test") } - task.setupCommandLine() + task.setupCommandLine("example-test", "com.example.test") assertEquals( listOf( @@ -109,4 +110,79 @@ class GenerateCodegenArtifactsTaskTest { ), task.commandLine.toMutableList()) } + + @Test + fun resolveTaskParameters_withConfigInPackageJson_usesIt() { + val packageJsonFile = + tempFolder.newFile("package.json").apply { + // language=JSON + writeText( + """ + { + "name": "@a/libray", + "codegenConfig": { + "name": "an-awesome-library", + "android": { + "javaPackageName": "com.awesome.package" + } + } + } + """.trimIndent()) + } + + val task = + createTestTask { + it.packageJsonFile.set(packageJsonFile) + it.codegenJavaPackageName.set("com.example.ignored") + it.libraryName.set("a-library-name-that-is-ignored") + } + + val (libraryName, javaPackageName) = task.resolveTaskParameters() + + assertEquals("an-awesome-library", libraryName) + assertEquals("com.awesome.package", javaPackageName) + } + + @Test + fun resolveTaskParameters_withConfigMissingInPackageJson_usesGradleOne() { + val packageJsonFile = + tempFolder.newFile("package.json").apply { + // language=JSON + writeText( + """ + { + "name": "@a/libray", + "codegenConfig": { + } + } + """.trimIndent()) + } + + val task = + createTestTask { + it.packageJsonFile.set(packageJsonFile) + it.codegenJavaPackageName.set("com.example.test") + it.libraryName.set("a-library-name-from-gradle") + } + + val (libraryName, javaPackageName) = task.resolveTaskParameters() + + assertEquals("a-library-name-from-gradle", libraryName) + assertEquals("com.example.test", javaPackageName) + } + + @Test + fun resolveTaskParameters_withMissingPackageJson_usesGradleOne() { + val task = + createTestTask { + it.packageJsonFile.set(File(tempFolder.root, "package.json")) + it.codegenJavaPackageName.set("com.example.test") + it.libraryName.set("a-library-name-from-gradle") + } + + val (libraryName, javaPackageName) = task.resolveTaskParameters() + + assertEquals("a-library-name-from-gradle", libraryName) + assertEquals("com.example.test", javaPackageName) + } } diff --git a/packages/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/JsonUtilsTest.kt b/packages/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/JsonUtilsTest.kt new file mode 100644 index 00000000000000..d52bd985ac03dd --- /dev/null +++ b/packages/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/JsonUtilsTest.kt @@ -0,0 +1,92 @@ +/* + * 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.utils + +import org.intellij.lang.annotations.Language +import org.junit.Assert.* +import org.junit.Rule +import org.junit.Test +import org.junit.rules.TemporaryFolder + +class JsonUtilsTest { + + @get:Rule val tempFolder = TemporaryFolder() + + @Test + fun withInvalidJson_returnsNull() { + val invalidJson = createJsonFile("""¯\_(ツ)_/¯""") + + assertNull(JsonUtils.fromCodegenJson(invalidJson)) + } + + @Test + fun withEmptyJson_returnsEmptyObject() { + val invalidJson = createJsonFile("""{}""") + + val parsed = JsonUtils.fromCodegenJson(invalidJson) + + assertNotNull(parsed) + assertNull(parsed?.codegenConfig) + } + + @Test + fun withOldJsonConfig_returnsAnEmptyLibrary() { + val oldJsonConfig = + createJsonFile( + """ + { + "name": "yet another npm package", + "codegenConfig": { + "libraries": [ + { + "name": "an awesome library", + "jsSrcsDir": "../js/", + "android": {} + } + ] + } + } + """.trimIndent()) + + val parsed = JsonUtils.fromCodegenJson(oldJsonConfig)!! + + assertNull(parsed.codegenConfig?.name) + assertNull(parsed.codegenConfig?.jsSrcsDir) + assertNull(parsed.codegenConfig?.android) + } + + @Test + fun withValidJson_parsesCorrectly() { + val validJson = + createJsonFile( + """ + { + "name": "yet another npm package", + "codegenConfig": { + "name": "an awesome library", + "jsSrcsDir": "../js/", + "android": { + "javaPackageName": "com.awesome.library" + }, + "ios": { + "other ios only keys": "which are ignored during parsing" + } + } + } + """.trimIndent()) + + val parsed = JsonUtils.fromCodegenJson(validJson)!! + + assertEquals("an awesome library", parsed.codegenConfig!!.name) + assertEquals("../js/", parsed.codegenConfig!!.jsSrcsDir) + assertEquals("com.awesome.library", parsed.codegenConfig!!.android!!.javaPackageName) + } + + private fun createJsonFile(@Language("JSON") input: String) = + tempFolder.newFile().apply { writeText(input) } +} diff --git a/packages/rn-tester/android/app/build.gradle b/packages/rn-tester/android/app/build.gradle index bd10c322f3956f..06c914e763f8c5 100644 --- a/packages/rn-tester/android/app/build.gradle +++ b/packages/rn-tester/android/app/build.gradle @@ -80,17 +80,15 @@ react { cliPath = "../../../../cli.js" bundleAssetName = "RNTesterApp.android.bundle" entryFile = file("../../js/RNTesterApp.android.js") - root = rootDir + root = file("../../") inputExcludes = ["android/**", "./**", ".gradle/**"] composeSourceMapsPath = "$rootDir/scripts/compose-source-maps.js" hermesCommand = "$rootDir/ReactAndroid/hermes-engine/build/hermes/bin/hermesc" enableHermesForVariant { def v -> v.name.contains("hermes") } // Codegen Configs - jsRootDir = file("$rootDir/packages/rn-tester") reactNativeDir = rootDir - libraryName = "rntester" - useJavaGenerator = System.getenv("USE_CODEGEN_JAVAPOET")?.toBoolean() ?: false + codegenDir = new File(rootDir, "node_modules/react-native-codegen") } project.ext.react = [ diff --git a/packages/rn-tester/android/app/src/main/jni/Android.mk b/packages/rn-tester/android/app/src/main/jni/Android.mk index a912fec85e1585..ec6991cfb589cd 100644 --- a/packages/rn-tester/android/app/src/main/jni/Android.mk +++ b/packages/rn-tester/android/app/src/main/jni/Android.mk @@ -15,7 +15,7 @@ LOCAL_PATH := $(THIS_DIR) include $(CLEAR_VARS) LOCAL_MODULE := rntester_appmodules -# Note: We are linking against react_codegen_rntester hence no need to built the react-native-codegen output. +# Note: We are linking against react_codegen_AppSpecs hence no need to built the react-native-codegen output. LOCAL_C_INCLUDES := $(LOCAL_PATH) $(GENERATED_SRC_DIR)/codegen/jni LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/*.cpp) LOCAL_SRC_FILES := $(subst $(LOCAL_PATH)/,,$(LOCAL_SRC_FILES)) @@ -26,7 +26,7 @@ LOCAL_SHARED_LIBRARIES := \ libfolly_runtime \ libglog \ libreact_codegen_rncore \ - libreact_codegen_rntester \ + libreact_codegen_AppSpecs \ libreact_debug \ libreact_nativemodule_core \ libreact_render_componentregistry \ diff --git a/packages/rn-tester/android/app/src/main/jni/RNTesterAppModuleProvider.cpp b/packages/rn-tester/android/app/src/main/jni/RNTesterAppModuleProvider.cpp index 76104b7455ccd9..5b55ce4a9de9bd 100644 --- a/packages/rn-tester/android/app/src/main/jni/RNTesterAppModuleProvider.cpp +++ b/packages/rn-tester/android/app/src/main/jni/RNTesterAppModuleProvider.cpp @@ -7,9 +7,9 @@ #include "RNTesterAppModuleProvider.h" +#include #include #include -#include namespace facebook { namespace react { @@ -17,7 +17,7 @@ namespace react { std::shared_ptr RNTesterAppModuleProvider( const std::string &moduleName, const JavaTurboModule::InitParams ¶ms) { - auto module = rntester_ModuleProvider(moduleName, params); + auto module = AppSpecs_ModuleProvider(moduleName, params); if (module != nullptr) { return module; } diff --git a/packages/rn-tester/android/app/src/main/jni/RNTesterComponentsRegistry.cpp b/packages/rn-tester/android/app/src/main/jni/RNTesterComponentsRegistry.cpp index 398bd4d2528037..ad8370b19e2311 100644 --- a/packages/rn-tester/android/app/src/main/jni/RNTesterComponentsRegistry.cpp +++ b/packages/rn-tester/android/app/src/main/jni/RNTesterComponentsRegistry.cpp @@ -10,8 +10,8 @@ #include #include #include +#include #include -#include namespace facebook { namespace react { diff --git a/packages/rn-tester/package.json b/packages/rn-tester/package.json index 4a34e465562613..6fbbfdb387c1d5 100644 --- a/packages/rn-tester/package.json +++ b/packages/rn-tester/package.json @@ -33,6 +33,9 @@ "codegenConfig": { "name": "AppSpecs", "type": "all", - "jsSrcsDir": "." + "jsSrcsDir": ".", + "android": { + "javaPackageName": "com.facebook.fbreact.specs" + } } }