Advertisement
Guest User

react.gradle

a guest
Sep 23rd, 2019
354
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.82 KB | None | 0 0
  1. // Copyright (c) Facebook, Inc. and its affiliates.
  2.  
  3. // This source code is licensed under the MIT license found in the
  4. // LICENSE file in the root directory of this source tree.
  5.  
  6. import org.apache.tools.ant.taskdefs.condition.Os
  7.  
  8. def config = project.hasProperty("react") ? project.react : [];
  9.  
  10. def cliPath = config.cliPath ?: "node_modules/react-native/cli.js"
  11. def composeSourceMapsPath = config.composeSourceMapsPath ?: "node_modules/react-native/scripts/compose-source-maps.js"
  12. def bundleAssetName = config.bundleAssetName ?: "index.android.bundle"
  13. def entryFile = config.entryFile ?: "index.android.js"
  14. def bundleCommand = config.bundleCommand ?: "bundle"
  15. def reactRoot = file(config.root ?: "../../")
  16. def inputExcludes = config.inputExcludes ?: ["android/**", "ios/**"]
  17. def bundleConfig = config.bundleConfig ? "${reactRoot}/${config.bundleConfig}" : null ;
  18. def enableVmCleanup = config.enableVmCleanup == null ? true : config.enableVmCleanup
  19. def hermesCommand = config.hermesCommand ?: "../../node_modules/hermesvm/%OS-BIN%/hermes"
  20.  
  21. def reactNativeDevServerPort() {
  22. def value = project.getProperties().get("reactNativeDevServerPort")
  23. return value != null ? value : "8081"
  24. }
  25.  
  26. def reactNativeInspectorProxyPort() {
  27. def value = project.getProperties().get("reactNativeInspectorProxyPort")
  28. return value != null ? value : reactNativeDevServerPort()
  29. }
  30.  
  31. def getHermesOSBin() {
  32. if (Os.isFamily(Os.FAMILY_WINDOWS)) return "win64-bin";
  33. if (Os.isFamily(Os.FAMILY_MAC)) return "osx-bin";
  34. if (Os.isOs(null, "linux", "amd64", null)) return "linux64-bin";
  35. throw new Exception("OS not recognized. Please set project.ext.react.hermesCommand " +
  36. "to the path of a working Hermes compiler.");
  37. }
  38.  
  39. // Make sure not to inspect the Hermes config unless we need it,
  40. // to avoid breaking any JSC-only setups.
  41. def getHermesCommand = {
  42. // If the project specifies a Hermes command, don't second guess it.
  43. if (!hermesCommand.contains("%OS-BIN%")) {
  44. return hermesCommand
  45. }
  46.  
  47. // Execution on Windows fails with / as separator
  48. return hermesCommand
  49. .replaceAll("%OS-BIN%", getHermesOSBin())
  50. .replace('/' as char, File.separatorChar);
  51. }
  52.  
  53. // Set enableHermesForVariant to a function to configure per variant,
  54. // or set `enableHermes` to True/False to set all of them
  55. def enableHermesForVariant = config.enableHermesForVariant ?: {
  56. def variant -> config.enableHermes ?: false
  57. }
  58.  
  59. android {
  60. buildTypes.all {
  61. resValue "integer", "react_native_dev_server_port", reactNativeDevServerPort()
  62. resValue "integer", "react_native_inspector_proxy_port", reactNativeInspectorProxyPort()
  63. }
  64. }
  65.  
  66. afterEvaluate {
  67. def isAndroidLibrary = plugins.hasPlugin("com.android.library")
  68. def variants = isAndroidLibrary ? android.libraryVariants : android.applicationVariants
  69. variants.all { def variant ->
  70. // Create variant and target names
  71. def targetName = variant.name.capitalize()
  72. def targetPath = variant.dirName
  73.  
  74. // React js bundle directories
  75. def jsBundleDir = file("$buildDir/generated/assets/react/${targetPath}")
  76. def resourcesDir = file("$buildDir/generated/res/react/${targetPath}")
  77.  
  78. def jsBundleFile = file("$jsBundleDir/$bundleAssetName")
  79. def jsSourceMapsDir = file("$buildDir/generated/sourcemaps/react/${targetPath}")
  80. def jsIntermediateSourceMapsDir = file("$buildDir/intermediates/sourcemaps/react/${targetPath}")
  81. def jsPackagerSourceMapFile = file("$jsIntermediateSourceMapsDir/${bundleAssetName}.packager.map")
  82. def jsCompilerSourceMapFile = file("$jsIntermediateSourceMapsDir/${bundleAssetName}.compiler.map")
  83. def jsOutputSourceMapFile = file("$jsSourceMapsDir/${bundleAssetName}.map")
  84.  
  85. // Additional node and packager commandline arguments
  86. def nodeExecutableAndArgs = config.nodeExecutableAndArgs ?: ["node"]
  87. def extraPackagerArgs = config.extraPackagerArgs ?: []
  88.  
  89. def enableHermes = enableHermesForVariant(variant)
  90.  
  91. def currentBundleTask = tasks.create(
  92. name: "bundle${targetName}JsAndAssets",
  93. type: Exec) {
  94. group = "react"
  95. description = "bundle JS and assets for ${targetName}."
  96.  
  97. // Create dirs if they are not there (e.g. the "clean" task just ran)
  98. doFirst {
  99. jsBundleDir.deleteDir()
  100. jsBundleDir.mkdirs()
  101. resourcesDir.deleteDir()
  102. resourcesDir.mkdirs()
  103. jsIntermediateSourceMapsDir.deleteDir()
  104. jsIntermediateSourceMapsDir.mkdirs()
  105. jsSourceMapsDir.deleteDir()
  106. jsSourceMapsDir.mkdirs()
  107. }
  108.  
  109. // Set up inputs and outputs so gradle can cache the result
  110. inputs.files fileTree(dir: reactRoot, excludes: inputExcludes)
  111. outputs.dir(jsBundleDir)
  112. outputs.dir(resourcesDir)
  113.  
  114. // Set up the call to the react-native cli
  115. workingDir(reactRoot)
  116.  
  117. // Set up dev mode
  118. def devEnabled = !(config."devDisabledIn${targetName}"
  119. || targetName.toLowerCase().contains("release"))
  120.  
  121. def extraArgs = extraPackagerArgs;
  122.  
  123. if (bundleConfig) {
  124. extraArgs = extraArgs.clone()
  125. extraArgs.add("--config");
  126. extraArgs.add(bundleConfig);
  127. }
  128.  
  129. if (Os.isFamily(Os.FAMILY_WINDOWS)) {
  130. commandLine("cmd", "/c", *nodeExecutableAndArgs, cliPath, bundleCommand, "--platform", "android", "--dev", "${devEnabled}",
  131. "--reset-cache", "--entry-file", entryFile, "--bundle-output", jsBundleFile, "--assets-dest", resourcesDir,
  132. "--sourcemap-output", enableHermes ? jsPackagerSourceMapFile : jsOutputSourceMapFile, *extraArgs)
  133. } else {
  134. commandLine(*nodeExecutableAndArgs, cliPath, bundleCommand, "--platform", "android", "--dev", "${devEnabled}",
  135. "--reset-cache", "--entry-file", entryFile, "--bundle-output", jsBundleFile, "--assets-dest", resourcesDir,
  136. "--sourcemap-output", enableHermes ? jsPackagerSourceMapFile : jsOutputSourceMapFile, *extraArgs)
  137. }
  138.  
  139. if (enableHermes) {
  140. doLast {
  141. def hermesFlags;
  142. exec {
  143. if (targetName.toLowerCase().contains("release")) {
  144. // Can't use ?: since that will also substitute valid empty lists
  145. hermesFlags = config.hermesFlagsRelease
  146. if (hermesFlags == null) hermesFlags = ["-O", "-output-source-map"]
  147. } else {
  148. hermesFlags = config.hermesFlagsDebug
  149. if (hermesFlags == null) hermesFlags = []
  150. }
  151. commandLine(getHermesCommand(), "-emit-binary", "-out", jsBundleFile, jsBundleFile, *hermesFlags)
  152. }
  153. if (hermesFlags.contains("-output-source-map")) {
  154. ant.move(
  155. // Hermes will generate a source map with this exact name
  156. // NOTE: name coincides with jsOutputSourceMapFile
  157. file: "${jsBundleFile}.map",
  158. tofile: jsCompilerSourceMapFile
  159. );
  160. exec {
  161. // TODO: set task dependencies for caching
  162.  
  163. // Set up the call to the compose-source-maps script
  164. workingDir(reactRoot)
  165. if (Os.isFamily(Os.FAMILY_WINDOWS)) {
  166. commandLine("cmd", "/c", *nodeExecutableAndArgs, composeSourceMapsPath, jsPackagerSourceMapFile, jsCompilerSourceMapFile, "-o", jsOutputSourceMapFile)
  167. } else {
  168. commandLine(*nodeExecutableAndArgs, composeSourceMapsPath, jsPackagerSourceMapFile, jsCompilerSourceMapFile, "-o", jsOutputSourceMapFile)
  169. }
  170. }
  171. }
  172. }
  173. }
  174.  
  175. enabled config."bundleIn${targetName}" != null
  176. ? config."bundleIn${targetName}"
  177. : config."bundleIn${variant.buildType.name.capitalize()}" != null
  178. ? config."bundleIn${variant.buildType.name.capitalize()}"
  179. : targetName.toLowerCase().contains("release")
  180. }
  181.  
  182. // Expose a minimal interface on the application variant and the task itself:
  183. variant.ext.bundleJsAndAssets = currentBundleTask
  184. currentBundleTask.ext.generatedResFolders = files(resourcesDir).builtBy(currentBundleTask)
  185. currentBundleTask.ext.generatedAssetsFolders = files(jsBundleDir).builtBy(currentBundleTask)
  186.  
  187. // registerGeneratedResFolders for Android plugin 3.x
  188. if (variant.respondsTo("registerGeneratedResFolders")) {
  189. variant.registerGeneratedResFolders(currentBundleTask.generatedResFolders)
  190. } else {
  191. variant.registerResGeneratingTask(currentBundleTask)
  192. }
  193. variant.mergeResourcesProvider.get().dependsOn(currentBundleTask)
  194.  
  195. // packageApplication for Android plugin 3.x
  196. def packageTask = variant.hasProperty("packageApplication")
  197. ? variant.packageApplicationProvider.get()
  198. : tasks.findByName("package${targetName}")
  199. if (variant.hasProperty("packageLibrary")) {
  200. packageTask = variant.packageLibrary
  201. }
  202.  
  203. // pre bundle build task for Android plugin 3.2+
  204. def buildPreBundleTask = tasks.findByName("build${targetName}PreBundle")
  205.  
  206. def resourcesDirConfigValue = config."resourcesDir${targetName}"
  207. if (resourcesDirConfigValue) {
  208. def currentCopyResTask = tasks.create(
  209. name: "copy${targetName}BundledResources",
  210. type: Copy) {
  211. group = "react"
  212. description = "copy bundled resources into custom location for ${targetName}."
  213.  
  214. from(resourcesDir)
  215. into(file(resourcesDirConfigValue))
  216.  
  217. dependsOn(currentBundleTask)
  218.  
  219. enabled(currentBundleTask.enabled)
  220. }
  221.  
  222. packageTask.dependsOn(currentCopyResTask)
  223. if (buildPreBundleTask != null) {
  224. buildPreBundleTask.dependsOn(currentCopyResTask)
  225. }
  226. }
  227.  
  228. def currentAssetsCopyTask = tasks.create(
  229. name: "copy${targetName}BundledJs",
  230. type: Copy) {
  231. group = "react"
  232. description = "copy bundled JS into ${targetName}."
  233.  
  234. if (config."jsBundleDir${targetName}") {
  235. from(jsBundleDir)
  236. into(file(config."jsBundleDir${targetName}"))
  237. } else {
  238. into ("$buildDir/intermediates")
  239. into ("assets/${targetPath}") {
  240. from(jsBundleDir)
  241. }
  242.  
  243. // Workaround for Android Gradle Plugin 3.2+ new asset directory
  244. into ("merged_assets/${variant.name}/merge${targetName}Assets/out") {
  245. from(jsBundleDir)
  246. }
  247.  
  248. // Workaround for Android Gradle Plugin 3.4+ new asset directory
  249. into ("merged_assets/${variant.name}/out") {
  250. from(jsBundleDir)
  251. }
  252. }
  253.  
  254. // mergeAssets must run first, as it clears the intermediates directory
  255. dependsOn(variant.mergeAssetsProvider.get())
  256.  
  257. enabled(currentBundleTask.enabled)
  258. }
  259.  
  260. packageTask.dependsOn(currentAssetsCopyTask)
  261. if (buildPreBundleTask != null) {
  262. buildPreBundleTask.dependsOn(currentAssetsCopyTask)
  263. }
  264.  
  265. // Delete the VM related libraries that this build doesn't need.
  266. // The application can manage this manually by setting 'enableVmCleanup: false'
  267. //
  268. // This should really be done by packaging all Hermes releated libs into
  269. // two separate HermesDebug and HermesRelease AARs, but until then we'll
  270. // kludge it by deleting the .so files out of the /transforms/ directory.
  271. def isRelease = targetName.toLowerCase().contains("release")
  272. def libDir = "$buildDir/intermediates/transforms/"
  273. def vmSelectionAction = {
  274. fileTree(libDir).matching {
  275. if (enableHermes) {
  276. // For Hermes, delete all the libjsc* files
  277. include "**/libjsc*.so"
  278.  
  279. if (isRelease) {
  280. // Reduce size by deleting the debugger/inspector
  281. include '**/libhermes-inspector.so'
  282. include '**/libhermes-executor-debug.so'
  283. } else {
  284. // Release libs take precedence and must be removed
  285. // to allow debugging
  286. include '**/libhermes-executor-release.so'
  287. }
  288. } else {
  289. // For JSC, delete all the libhermes* files
  290. include "**/libhermes*.so"
  291. }
  292. }.visit { details ->
  293. def targetVariant = ".*/transforms/[^/]*/${targetPath}/.*"
  294. def path = details.file.getAbsolutePath().replace(File.separatorChar, '/' as char)
  295. if (path.matches(targetVariant) && details.file.isFile()) {
  296. details.file.delete()
  297. }
  298. }
  299. }
  300.  
  301. if (enableVmCleanup) {
  302. def task = tasks.findByName("package${targetName}")
  303. task.doFirst(vmSelectionAction)
  304. }
  305. }
  306. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement