Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ project.xcworkspace
/build/
/packages/react-native-codegen/android/build/
/packages/react-native-codegen/android/gradlePlugin-build/gradlePlugin/build
/packages/react-native-gradle-plugin/build/
/packages/rn-tester/android/app/.cxx/
/packages/rn-tester/android/app/build/
/packages/rn-tester/android/app/gradle/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1002,6 +1002,9 @@ private void recreateReactContextInBackground(
private void runCreateReactContextOnNewThread(final ReactContextInitParams initParams) {
FLog.d(ReactConstants.TAG, "ReactInstanceManager.runCreateReactContextOnNewThread()");
UiThreadUtil.assertOnUiThread();

// Mark start of bridge loading
ReactMarker.logMarker(ReactMarkerConstants.REACT_BRIDGE_LOADING_START);
synchronized (mAttachedReactRoots) {
synchronized (mReactContextLock) {
if (mCurrentReactContext != null) {
Expand Down Expand Up @@ -1133,6 +1136,8 @@ public void run() {
});
Systrace.endSection(TRACE_TAG_REACT_JAVA_BRIDGE);
ReactMarker.logMarker(SETUP_REACT_CONTEXT_END);
// Mark end of bridge loading
ReactMarker.logMarker(ReactMarkerConstants.REACT_BRIDGE_LOADING_END);
reactContext.runOnJSQueueThread(
new Runnable() {
@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,9 @@ public enum ReactMarkerConstants {
FABRIC_BATCH_EXECUTION_END,
FABRIC_UPDATE_UI_MAIN_THREAD_START,
FABRIC_UPDATE_UI_MAIN_THREAD_END,
// New markers used by bridgeless RN below this line
REACT_INSTANCE_INIT_START,
REACT_INSTANCE_INIT_END
// New markers used by bridge and bridgeless loading below this line
REACT_BRIDGE_LOADING_START,
REACT_BRIDGE_LOADING_END,
REACT_BRIDGELESS_LOADING_START,
REACT_BRIDGELESS_LOADING_END
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ plugins {

gradlePlugin {
plugins {
greeting {
codegen {
id = 'com.facebook.react.codegen'
implementationClass = 'com.facebook.react.codegen.plugin.CodegenPlugin'
}
Expand Down
30 changes: 30 additions & 0 deletions packages/react-native-gradle-plugin/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

plugins {
`java-gradle-plugin`
`kotlin-dsl`
kotlin("jvm") version "1.4.21"
}

repositories {
google()
jcenter()
}

gradlePlugin {
plugins {
create("reactApp") {
id = "com.facebook.react.app"
implementationClass = "com.facebook.react.ReactAppPlugin"
}
}
}

dependencies {
implementation("com.android.tools.build:gradle:4.1.0")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Copyright (c) Facebook, Inc. and its 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

import com.android.build.gradle.BaseExtension
import org.gradle.api.Project

fun Project.configureDevPorts(androidExt: BaseExtension) {
val devServerPort = project.properties["reactNativeDevServerPort"]?.toString() ?: "8081"
val inspectorProxyPort = project.properties["reactNativeInspectorProxyPort"]?.toString() ?: devServerPort

androidExt.buildTypes.all {
resValue("integer", "react_native_dev_server_port", devServerPort)
resValue("integer", "react_native_inspector_proxy_port", inspectorProxyPort)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/*
* Copyright (c) Facebook, Inc. and its 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

import com.android.build.gradle.api.BaseVariant
import org.apache.tools.ant.taskdefs.condition.Os
import org.gradle.api.Project
import java.io.File

open class ReactAppExtension(private val project: Project) {
var composeSourceMapsPath: String = "node_modules/react-native/scripts/compose-source-maps.js"
var bundleAssetName: String = "index.android.bundle"
var entryFile: File? = null
var bundleCommand: String = "bundle"
var reactRoot: File = File(project.projectDir, "../../")
var inputExcludes: List<String> = listOf("android/**", "ios/**")
var bundleConfig: String? = null
var enableVmCleanup: Boolean = true
var hermesCommand: String = "node_modules/hermes-engine/%OS-BIN%/hermesc"
var cliPath: String? = null
var nodeExecutableAndArgs: List<String> = listOf("node")
var enableHermes: Boolean = false
var enableHermesForVariant: (BaseVariant) -> Boolean = { enableHermes }
var devDisabledInVariants: List<String> = emptyList()
// todo maybe lambda as for hermes?
var bundleIn: Map<String, Boolean> = emptyMap()
var extraPackagerArgs: List<String> = emptyList()
var hermesFlagsDebug: List<String> = emptyList()
var hermesFlagsRelease: List<String> = listOf("-O", "-output-source-map")
var resourcesDir: Map<String, File> = emptyMap()
var jsBundleDir: Map<String, File> = emptyMap()

internal val detectedEntryFile: File
get() = detectEntryFile(entryFile = entryFile, reactRoot = reactRoot)

internal val detectedCliPath: String
get() = detectCliPath(
projectDir = project.projectDir,
reactRoot = reactRoot,
preconfuredCliPath = cliPath
)

internal val osAwareHermesCommand: String
get() = getOSAwareHermesCommand(hermesCommand)

private fun detectEntryFile(entryFile: File?, reactRoot: File): File = when {
System.getenv("ENTRY_FILE") != null -> File(System.getenv("ENTRY_FILE"))
entryFile != null -> entryFile
File(reactRoot, "index.android.js").exists() -> File(reactRoot, "index.android.js")
else -> File(reactRoot, "index.android.js")
}

private fun detectCliPath(projectDir: File, reactRoot: File, preconfuredCliPath: String?): String {
// 1. preconfigured path
if (preconfuredCliPath != null) return preconfuredCliPath

// 2. node module path
val nodeProcess = Runtime.getRuntime().exec(
arrayOf("node", "-e", "console.log(require('react-native/cli').bin);"),
emptyArray(),
projectDir
)

val nodeProcessOutput = nodeProcess.inputStream.use {
it.bufferedReader().readText().trim()
}

if (nodeProcessOutput.isNotEmpty()) {
return nodeProcessOutput
}

// 3. cli.js in the root folder
val rootCliJs = File(reactRoot, "node_modules/react-native/cli.js")
if (rootCliJs.exists()) {
return rootCliJs.absolutePath
}

error("Couldn't determine CLI location. " +
"Please set `project.react.cliPath` to the path of the react-native cli.js")
}

// Make sure not to inspect the Hermes config unless we need it,
// to avoid breaking any JSC-only setups.
private fun getOSAwareHermesCommand(hermesCommand: String): String {
// If the project specifies a Hermes command, don't second guess it.
if (!hermesCommand.contains("%OS-BIN%")) {
return hermesCommand
}

// Execution on Windows fails with / as separator
return hermesCommand
.replace("%OS-BIN%", getHermesOSBin())
.replace('/', File.separatorChar)
}

private fun getHermesOSBin(): String {
if (Os.isFamily(Os.FAMILY_WINDOWS)) return "win64-bin"
if (Os.isFamily(Os.FAMILY_MAC)) return "osx-bin"
if (Os.isOs(null, "linux", "amd64", null)) return "linux64-bin"
error("OS not recognized. Please set project.react.hermesCommand " +
"to the path of a working Hermes compiler.")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright (c) Facebook, Inc. and its 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

import com.android.build.gradle.AppExtension
import com.android.build.gradle.BaseExtension
import com.android.build.gradle.LibraryExtension
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.create
import org.gradle.kotlin.dsl.getByType

class ReactAppPlugin : Plugin<Project> {
override fun apply(project: Project) {
val config = project.extensions.create<ReactAppExtension>("reactApp", project)

project.afterEvaluate {
val androidConfiguration = extensions.getByType<BaseExtension>()
configureDevPorts(androidConfiguration)

val isAndroidLibrary = plugins.hasPlugin("com.android.library")
val variants = if (isAndroidLibrary) {
extensions.getByType<LibraryExtension>().libraryVariants
} else {
extensions.getByType<AppExtension>().applicationVariants
}
variants.all {
configureReactTasks(
variant = this,
config = config
)
}
}
}
}
Loading