mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
995b4d3049
Summary: ### Problem According to https://github.com/facebook/react-native/issues/9145, the `--port` setting is not respected when executing `react-native run-android`. The templates that report things like what port the dev server runs on are hard coded as well. ### Solution This commit replaces the hardcoded instances of port 8081 on Android with a build configuration property. This allows setting of the port React Native Android connects to for the local build server. For this change to work, there must also be an update to the react native CLI to pass along this setting: https://github.com/react-native-community/react-native-cli/compare/master...nhunzaker:9145-android-no-port-hardcode-cli To avoid some noise on their end, I figured I wouldn't submit a PR until it's this approach is deemed workable. ## Changelog [Android][fixed] - `react-native run-android --port <x>` correctly connects to dev server and related error messages display the correct port Pull Request resolved: https://github.com/facebook/react-native/pull/23616 Differential Revision: D15645200 Pulled By: cpojer fbshipit-source-id: 3bdfd458b8ac3ec78290736c9ed0db2e5776ed46
213 lines
8.7 KiB
Groovy
213 lines
8.7 KiB
Groovy
// 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.
|
|
|
|
import org.apache.tools.ant.taskdefs.condition.Os
|
|
|
|
def config = project.hasProperty("react") ? project.react : [];
|
|
|
|
def cliPath = config.cliPath ?: "node_modules/react-native/cli.js"
|
|
def bundleAssetName = config.bundleAssetName ?: "index.android.bundle"
|
|
def entryFile = config.entryFile ?: "index.android.js"
|
|
def bundleCommand = config.bundleCommand ?: "bundle"
|
|
def reactRoot = file(config.root ?: "../../")
|
|
def inputExcludes = config.inputExcludes ?: ["android/**", "ios/**"]
|
|
def bundleConfig = config.bundleConfig ? "${reactRoot}/${config.bundleConfig}" : null ;
|
|
|
|
def reactNativeDevServerPort() {
|
|
def value = project.getProperties().get("reactNativeDevServerPort")
|
|
return value != null ? value : "8081"
|
|
}
|
|
|
|
def reactNativeInspectorProxyPort() {
|
|
def value = project.getProperties().get("reactNativeInspectorProxyPort")
|
|
return value != null ? value : reactNativeDevServerPort()
|
|
}
|
|
|
|
android {
|
|
buildTypes.all {
|
|
resValue "integer", "react_native_dev_server_port", reactNativeDevServerPort()
|
|
resValue "integer", "react_native_inspector_proxy_port", reactNativeInspectorProxyPort()
|
|
}
|
|
}
|
|
|
|
afterEvaluate {
|
|
def isAndroidLibrary = plugins.hasPlugin("com.android.library")
|
|
def variants = isAndroidLibrary ? android.libraryVariants : android.applicationVariants
|
|
variants.all { def variant ->
|
|
// Create variant and target names
|
|
def targetName = variant.name.capitalize()
|
|
def targetPath = variant.dirName
|
|
|
|
// React js bundle directories
|
|
def jsBundleDir = file("$buildDir/generated/assets/react/${targetPath}")
|
|
def resourcesDir = file("$buildDir/generated/res/react/${targetPath}")
|
|
|
|
def jsBundleFile = file("$jsBundleDir/$bundleAssetName")
|
|
|
|
// Additional node and packager commandline arguments
|
|
def nodeExecutableAndArgs = config.nodeExecutableAndArgs ?: ["node"]
|
|
def extraPackagerArgs = config.extraPackagerArgs ?: []
|
|
|
|
def currentBundleTask = tasks.create(
|
|
name: "bundle${targetName}JsAndAssets",
|
|
type: Exec) {
|
|
group = "react"
|
|
description = "bundle JS and assets for ${targetName}."
|
|
|
|
// Create dirs if they are not there (e.g. the "clean" task just ran)
|
|
doFirst {
|
|
jsBundleDir.deleteDir()
|
|
jsBundleDir.mkdirs()
|
|
resourcesDir.deleteDir()
|
|
resourcesDir.mkdirs()
|
|
}
|
|
|
|
|
|
// If there are flavors, remember the current flavor for use in the resource path we move from
|
|
def flavorPathSegment = ""
|
|
android.productFlavors.all { flavor ->
|
|
if (targetName.toLowerCase().contains(flavor.name)) {
|
|
flavorPathSegment = flavor.name + "/"
|
|
}
|
|
}
|
|
|
|
// Address issue #22234 by moving generated resources into build dir so they are in one spot, not duplicated
|
|
doLast {
|
|
def moveFunc = { resSuffix ->
|
|
File originalDir = file("$buildDir/generated/res/react/${flavorPathSegment}release/${resSuffix}")
|
|
if (originalDir.exists()) {
|
|
File destDir = file("$buildDir/../src/main/res/${resSuffix}")
|
|
ant.move(file: originalDir, tofile: destDir);
|
|
}
|
|
}
|
|
moveFunc.curry("drawable-ldpi").call()
|
|
moveFunc.curry("drawable-mdpi").call()
|
|
moveFunc.curry("drawable-hdpi").call()
|
|
moveFunc.curry("drawable-xhdpi").call()
|
|
moveFunc.curry("drawable-xxhdpi").call()
|
|
moveFunc.curry("drawable-xxxhdpi").call()
|
|
moveFunc.curry("raw").call()
|
|
}
|
|
|
|
// Set up inputs and outputs so gradle can cache the result
|
|
inputs.files fileTree(dir: reactRoot, excludes: inputExcludes)
|
|
outputs.dir(jsBundleDir)
|
|
outputs.dir(resourcesDir)
|
|
|
|
// Set up the call to the react-native cli
|
|
workingDir(reactRoot)
|
|
|
|
// Set up dev mode
|
|
def devEnabled = !(config."devDisabledIn${targetName}"
|
|
|| targetName.toLowerCase().contains("release"))
|
|
|
|
def extraArgs = extraPackagerArgs;
|
|
|
|
if (bundleConfig) {
|
|
extraArgs = extraArgs.clone()
|
|
extraArgs.add("--config");
|
|
extraArgs.add(bundleConfig);
|
|
}
|
|
|
|
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
|
|
commandLine("cmd", "/c", *nodeExecutableAndArgs, cliPath, bundleCommand, "--platform", "android", "--dev", "${devEnabled}",
|
|
"--reset-cache", "--entry-file", entryFile, "--bundle-output", jsBundleFile, "--assets-dest", resourcesDir, *extraArgs)
|
|
} else {
|
|
commandLine(*nodeExecutableAndArgs, cliPath, bundleCommand, "--platform", "android", "--dev", "${devEnabled}",
|
|
"--reset-cache", "--entry-file", entryFile, "--bundle-output", jsBundleFile, "--assets-dest", resourcesDir, *extraArgs)
|
|
}
|
|
|
|
enabled config."bundleIn${targetName}" != null
|
|
? config."bundleIn${targetName}"
|
|
: config."bundleIn${variant.buildType.name.capitalize()}" != null
|
|
? config."bundleIn${variant.buildType.name.capitalize()}"
|
|
: targetName.toLowerCase().contains("release")
|
|
}
|
|
|
|
// Expose a minimal interface on the application variant and the task itself:
|
|
variant.ext.bundleJsAndAssets = currentBundleTask
|
|
currentBundleTask.ext.generatedResFolders = files(resourcesDir).builtBy(currentBundleTask)
|
|
currentBundleTask.ext.generatedAssetsFolders = files(jsBundleDir).builtBy(currentBundleTask)
|
|
|
|
// registerGeneratedResFolders for Android plugin 3.x
|
|
if (variant.respondsTo("registerGeneratedResFolders")) {
|
|
variant.registerGeneratedResFolders(currentBundleTask.generatedResFolders)
|
|
} else {
|
|
variant.registerResGeneratingTask(currentBundleTask)
|
|
}
|
|
variant.mergeResourcesProvider.get().dependsOn(currentBundleTask)
|
|
|
|
// packageApplication for Android plugin 3.x
|
|
def packageTask = variant.hasProperty("packageApplication")
|
|
? variant.packageApplicationProvider.get()
|
|
: tasks.findByName("package${targetName}")
|
|
if (variant.hasProperty("packageLibrary")) {
|
|
packageTask = variant.packageLibrary
|
|
}
|
|
|
|
// pre bundle build task for Android plugin 3.2+
|
|
def buildPreBundleTask = tasks.findByName("build${targetName}PreBundle")
|
|
|
|
def resourcesDirConfigValue = config."resourcesDir${targetName}"
|
|
if (resourcesDirConfigValue) {
|
|
def currentCopyResTask = tasks.create(
|
|
name: "copy${targetName}BundledResources",
|
|
type: Copy) {
|
|
group = "react"
|
|
description = "copy bundled resources into custom location for ${targetName}."
|
|
|
|
from(resourcesDir)
|
|
into(file(resourcesDirConfigValue))
|
|
|
|
dependsOn(currentBundleTask)
|
|
|
|
enabled(currentBundleTask.enabled)
|
|
}
|
|
|
|
packageTask.dependsOn(currentCopyResTask)
|
|
if (buildPreBundleTask != null) {
|
|
buildPreBundleTask.dependsOn(currentCopyResTask)
|
|
}
|
|
}
|
|
|
|
def currentAssetsCopyTask = tasks.create(
|
|
name: "copy${targetName}BundledJs",
|
|
type: Copy) {
|
|
group = "react"
|
|
description = "copy bundled JS into ${targetName}."
|
|
|
|
if (config."jsBundleDir${targetName}") {
|
|
from(jsBundleDir)
|
|
into(file(config."jsBundleDir${targetName}"))
|
|
} else {
|
|
into ("$buildDir/intermediates")
|
|
into ("assets/${targetPath}") {
|
|
from(jsBundleDir)
|
|
}
|
|
|
|
// Workaround for Android Gradle Plugin 3.2+ new asset directory
|
|
into ("merged_assets/${variant.name}/merge${targetName}Assets/out") {
|
|
from(jsBundleDir)
|
|
}
|
|
|
|
// Workaround for Android Gradle Plugin 3.4+ new asset directory
|
|
into ("merged_assets/${variant.name}/out") {
|
|
from(jsBundleDir)
|
|
}
|
|
}
|
|
|
|
// mergeAssets must run first, as it clears the intermediates directory
|
|
dependsOn(variant.mergeAssetsProvider.get())
|
|
|
|
enabled(currentBundleTask.enabled)
|
|
}
|
|
|
|
packageTask.dependsOn(currentAssetsCopyTask)
|
|
if (buildPreBundleTask != null) {
|
|
buildPreBundleTask.dependsOn(currentAssetsCopyTask)
|
|
}
|
|
}
|
|
}
|