Skip to content

Commit 78577cc

Browse files
committed
AAPT2-compatible Android build process integration
1 parent cc6d093 commit 78577cc

File tree

1 file changed

+102
-97
lines changed

1 file changed

+102
-97
lines changed

react.gradle

Lines changed: 102 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -6,112 +6,117 @@ def cliPath = config.cliPath ?: "node_modules/react-native/local-cli/cli.js"
66
def bundleAssetName = config.bundleAssetName ?: "index.android.bundle"
77
def entryFile = config.entryFile ?: "index.android.js"
88
def bundleCommand = config.bundleCommand ?: "bundle"
9-
10-
// because elvis operator
11-
def elvisFile(thing) {
12-
return thing ? file(thing) : null;
13-
}
14-
15-
def reactRoot = elvisFile(config.root) ?: file("../../")
9+
def reactRoot = file(config.root ?: "../../")
1610
def inputExcludes = config.inputExcludes ?: ["android/**", "ios/**"]
1711
def bundleConfig = config.bundleConfig ? "${reactRoot}/${config.bundleConfig}" : null ;
1812

19-
void runBefore(String dependentTaskName, Task task) {
20-
Task dependentTask = tasks.findByPath(dependentTaskName);
21-
if (dependentTask != null) {
22-
dependentTask.dependsOn task
23-
}
24-
}
2513

2614
gradle.projectsEvaluated {
27-
// Grab all build types and product flavors
28-
def buildTypes = android.buildTypes.collect { type -> type.name }
29-
def productFlavors = android.productFlavors.collect { flavor -> flavor.name }
30-
31-
// When no product flavors defined, use empty
32-
if (!productFlavors) productFlavors.add('')
33-
34-
productFlavors.each { productFlavorName ->
35-
buildTypes.each { buildTypeName ->
36-
// Create variant and target names
37-
def flavorNameCapitalized = "${productFlavorName.capitalize()}"
38-
def buildNameCapitalized = "${buildTypeName.capitalize()}"
39-
def targetName = "${flavorNameCapitalized}${buildNameCapitalized}"
40-
def targetPath = productFlavorName ?
41-
"${productFlavorName}/${buildTypeName}" :
42-
"${buildTypeName}"
43-
44-
// React js bundle directories
45-
def jsBundleDirConfigName = "jsBundleDir${targetName}"
46-
def jsBundleDir = elvisFile(config."$jsBundleDirConfigName") ?:
47-
file("$buildDir/intermediates/assets/${targetPath}")
48-
49-
def resourcesDirConfigName = "resourcesDir${targetName}"
50-
def resourcesDir = elvisFile(config."${resourcesDirConfigName}") ?:
51-
file("$buildDir/intermediates/res/merged/${targetPath}")
52-
def jsBundleFile = file("$jsBundleDir/$bundleAssetName")
53-
54-
// Bundle task name for variant
55-
def bundleJsAndAssetsTaskName = "bundle${targetName}JsAndAssets"
56-
57-
// Additional node and packager commandline arguments
58-
def nodeExecutableAndArgs = config.nodeExecutableAndArgs ?: ["node"]
59-
def extraPackagerArgs = config.extraPackagerArgs ?: []
60-
61-
def currentBundleTask = tasks.create(
62-
name: bundleJsAndAssetsTaskName,
63-
type: Exec) {
15+
android.applicationVariants.all { def variant ->
16+
// Create variant and target names
17+
def targetName = variant.name.capitalize()
18+
def targetPath = variant.dirName
19+
20+
// React js bundle directories
21+
def jsBundleDir = file("$buildDir/generated/assets/react/${targetPath}")
22+
def resourcesDir = file("$buildDir/generated/res/react/${targetPath}")
23+
24+
def jsBundleFile = file("$jsBundleDir/$bundleAssetName")
25+
26+
// Additional node and packager commandline arguments
27+
def nodeExecutableAndArgs = config.nodeExecutableAndArgs ?: ["node"]
28+
def extraPackagerArgs = config.extraPackagerArgs ?: []
29+
30+
def currentBundleTask = tasks.create(
31+
name: "bundle${targetName}JsAndAssets",
32+
type: Exec) {
33+
group = "react"
34+
description = "bundle JS and assets for ${targetName}."
35+
36+
// Create dirs if they are not there (e.g. the "clean" task just ran)
37+
doFirst {
38+
jsBundleDir.deleteDir()
39+
jsBundleDir.mkdirs()
40+
resourcesDir.deleteDir()
41+
resourcesDir.mkdirs()
42+
}
43+
44+
// Set up inputs and outputs so gradle can cache the result
45+
inputs.files fileTree(dir: reactRoot, excludes: inputExcludes)
46+
outputs.dir jsBundleDir
47+
outputs.dir resourcesDir
48+
49+
// Set up the call to the react-native cli
50+
workingDir reactRoot
51+
52+
// Set up dev mode
53+
def devEnabled = !(config."devDisabledIn${targetName}"
54+
|| targetName.toLowerCase().contains("release"))
55+
56+
def extraArgs = extraPackagerArgs;
57+
58+
if (bundleConfig) {
59+
extraArgs = extraArgs.clone()
60+
extraArgs.add("--config");
61+
extraArgs.add(bundleConfig);
62+
}
63+
64+
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
65+
commandLine("cmd", "/c", *nodeExecutableAndArgs, cliPath, bundleCommand, "--platform", "android", "--dev", "${devEnabled}",
66+
"--reset-cache", "--entry-file", entryFile, "--bundle-output", jsBundleFile, "--assets-dest", resourcesDir, *extraArgs)
67+
} else {
68+
commandLine(*nodeExecutableAndArgs, cliPath, bundleCommand, "--platform", "android", "--dev", "${devEnabled}",
69+
"--reset-cache", "--entry-file", entryFile, "--bundle-output", jsBundleFile, "--assets-dest", resourcesDir, *extraArgs)
70+
}
71+
72+
enabled config."bundleIn${targetName}" ||
73+
config."bundleIn${variant.buildType.name.capitalize()}" ?:
74+
targetName.toLowerCase().contains("release")
75+
}
76+
77+
// Expose a minimal interface on the application variant and the task itself:
78+
variant.ext.bundleJsAndAssets = currentBundleTask
79+
currentBundleTask.ext.generatedResFolders = files(resourcesDir).builtBy(currentBundleTask)
80+
currentBundleTask.ext.generatedAssetsFolders = files(jsBundleDir).builtBy(currentBundleTask)
81+
82+
variant.registerGeneratedResFolders(currentBundleTask.generatedResFolders)
83+
variant.mergeResources.dependsOn(currentBundleTask)
84+
85+
def resourcesDirConfigValue = config."resourcesDir${targetName}"
86+
if (resourcesDirConfigValue) {
87+
def currentCopyResTask = tasks.create(
88+
name: "copy${targetName}BundledResources",
89+
type: Copy) {
6490
group = "react"
65-
description = "bundle JS and assets for ${targetName}."
66-
67-
// Create dirs if they are not there (e.g. the "clean" task just ran)
68-
doFirst {
69-
jsBundleDir.mkdirs()
70-
resourcesDir.mkdirs()
71-
}
72-
73-
// Set up inputs and outputs so gradle can cache the result
74-
inputs.files fileTree(dir: reactRoot, excludes: inputExcludes)
75-
outputs.dir jsBundleDir
76-
outputs.dir resourcesDir
77-
78-
// Set up the call to the react-native cli
79-
workingDir reactRoot
80-
81-
// Set up dev mode
82-
def devEnabled = !(config."devDisabledIn${targetName}"
83-
|| targetName.toLowerCase().contains("release"))
84-
85-
def extraArgs = extraPackagerArgs;
86-
87-
if (bundleConfig) {
88-
extraArgs = extraArgs.clone()
89-
extraArgs.add("--config");
90-
extraArgs.add(bundleConfig);
91-
}
92-
93-
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
94-
commandLine("cmd", "/c", *nodeExecutableAndArgs, cliPath, bundleCommand, "--platform", "android", "--dev", "${devEnabled}",
95-
"--reset-cache", "--entry-file", entryFile, "--bundle-output", jsBundleFile, "--assets-dest", resourcesDir, *extraArgs)
96-
} else {
97-
commandLine(*nodeExecutableAndArgs, cliPath, bundleCommand, "--platform", "android", "--dev", "${devEnabled}",
98-
"--reset-cache", "--entry-file", entryFile, "--bundle-output", jsBundleFile, "--assets-dest", resourcesDir, *extraArgs)
99-
}
100-
101-
enabled config."bundleIn${targetName}" ||
102-
config."bundleIn${buildTypeName.capitalize()}" ?:
103-
targetName.toLowerCase().contains("release")
91+
description = "copy bundled resources into custom location for ${targetName}."
92+
93+
from resourcesDir
94+
into file(resourcesDirConfigValue)
95+
96+
dependsOn(currentBundleTask)
97+
98+
enabled currentBundleTask.enabled
10499
}
105100

106-
// Hook bundle${productFlavor}${buildType}JsAndAssets into the android build process
107-
currentBundleTask.dependsOn("merge${targetName}Resources")
108-
currentBundleTask.dependsOn("merge${targetName}Assets")
101+
variant.packageApplication.dependsOn(currentCopyResTask)
102+
}
103+
104+
def currentAssetsCopyTask = tasks.create(
105+
name: "copy${targetName}BundledJs",
106+
type: Copy) {
107+
group = "react"
108+
description = "copy bundled JS into ${targetName}."
109109

110-
runBefore("process${flavorNameCapitalized}Armeabi-v7a${buildNameCapitalized}Resources", currentBundleTask)
111-
runBefore("process${flavorNameCapitalized}X86${buildNameCapitalized}Resources", currentBundleTask)
112-
runBefore("processUniversal${targetName}Resources", currentBundleTask)
113-
runBefore("process${targetName}Resources", currentBundleTask)
114-
runBefore("dataBindingProcessLayouts${targetName}", currentBundleTask)
110+
from jsBundleDir
111+
into file(config."jsBundleDir${targetName}" ?:
112+
"$buildDir/intermediates/assets/${targetPath}")
113+
114+
// mergeAssets must run first, as it clears the intermediates directory
115+
dependsOn(variant.mergeAssets)
116+
117+
enabled currentBundleTask.enabled
115118
}
119+
120+
variant.packageApplication.dependsOn(currentAssetsCopyTask)
116121
}
117122
}

0 commit comments

Comments
 (0)