Skip to content

Commit 2df63e5

Browse files
cortinicofacebook-github-bot
authored andcommitted
RNGP - Use the File Api to specify cliPath and remove ComposeSourceMap path (#35092)
Summary: Pull Request resolved: #35092 As we're close to the cut of the 0.71 branch, I'll take the opportunity to polish our Gradle public API. We're exposing a mixture of Path (String) and File (java.io.File or RegularFileProperty). Here I've moved everything to use File as it's more configurable for the users, specifically if they're using monorepos or other setup. This also allows us to remove the resolution logic for the cliPath. Changelog: [Internal] [Changed] - RNGP - Use the File Api to specify cliPath and remove ComposeSourceMap path Reviewed By: cipolleschi Differential Revision: D40710595 fbshipit-source-id: a17095eebae5123b70fd2b8e3d512656817006ca
1 parent 1069841 commit 2df63e5

File tree

7 files changed

+78
-146
lines changed

7 files changed

+78
-146
lines changed

packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/ReactExtension.kt

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,26 @@ abstract class ReactExtension @Inject constructor(project: Project) {
2828
val root: DirectoryProperty =
2929
objects.directoryProperty().convention(project.rootProject.layout.projectDirectory.dir("../"))
3030

31+
/**
32+
* The path to the react-native NPM package folder.
33+
*
34+
* Default: ${rootProject.dir}/../node_modules/react-native-codegen
35+
*/
36+
val reactNativeDir: DirectoryProperty =
37+
objects.directoryProperty().convention(root.dir("node_modules/react-native"))
38+
3139
/**
3240
* The path to the JS entry file. If not specified, the plugin will try to resolve it using a list
3341
* of known locations (e.g. `index.android.js`, `index.js`, etc.).
3442
*/
3543
val entryFile: RegularFileProperty = objects.fileProperty()
3644

3745
/**
38-
* The path to the React Native CLI. If not specified, the plugin will try to resolve it looking
39-
* for `react-native` CLI inside `node_modules` in [root].
46+
* The reference to the React Native CLI. If not specified, the plugin will try to resolve it
47+
* looking for `react-native` CLI inside `node_modules` in [root].
4048
*/
41-
val cliPath: Property<String> = objects.property(String::class.java)
49+
val cliFile: RegularFileProperty =
50+
objects.fileProperty().convention(reactNativeDir.file("cli.js"))
4251

4352
/**
4453
* The path to the Node executable and extra args. By default it assumes that you have `node`
@@ -107,15 +116,6 @@ abstract class ReactExtension @Inject constructor(project: Project) {
107116
val hermesFlags: ListProperty<String> =
108117
objects.listProperty(String::class.java).convention(listOf("-O", "-output-source-map"))
109118

110-
/**
111-
* The path to the Compose Source Map script. Default:
112-
* "node_modules/react-native/scripts/compose-source-maps.js"
113-
*/
114-
val composeSourceMapsPath: Property<String> =
115-
objects
116-
.property(String::class.java)
117-
.convention("node_modules/react-native/scripts/compose-source-maps.js")
118-
119119
/** Codegen Config */
120120

121121
/**
@@ -126,14 +126,6 @@ abstract class ReactExtension @Inject constructor(project: Project) {
126126
val codegenDir: DirectoryProperty =
127127
objects.directoryProperty().convention(root.dir("node_modules/react-native-codegen"))
128128

129-
/**
130-
* The path to the react-native NPM package folder.
131-
*
132-
* Default: ${rootProject.dir}/../node_modules/react-native-codegen
133-
*/
134-
val reactNativeDir: DirectoryProperty =
135-
objects.directoryProperty().convention(root.dir("node_modules/react-native"))
136-
137129
/**
138130
* The root directory for all JS files for the app.
139131
*

packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/TaskConfiguration.kt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import com.facebook.react.tasks.BundleHermesCTask
1212
import com.facebook.react.utils.NdkConfiguratorUtils.configureJsEnginePackagingOptions
1313
import com.facebook.react.utils.NdkConfiguratorUtils.configureNewArchPackagingOptions
1414
import com.facebook.react.utils.ProjectUtils.isHermesEnabled
15-
import com.facebook.react.utils.detectedCliPath
15+
import com.facebook.react.utils.detectedCliFile
1616
import com.facebook.react.utils.detectedEntryFile
1717
import java.io.File
1818
import org.gradle.api.Project
@@ -32,8 +32,8 @@ internal fun Project.configureReactTasks(variant: Variant, config: ReactExtensio
3232
// Intermediate compiler: intermediates/sourcemaps/react/path/index.android.bundle.compiler.map
3333
val jsIntermediateSourceMapsDir = File(buildDir, "intermediates/sourcemaps/react/$targetPath")
3434

35-
// Additional node and packager commandline arguments
36-
val cliPath = detectedCliPath(project.projectDir, config)
35+
// The location of the cli.js file for React Native
36+
val cliFile = detectedCliFile(config)
3737

3838
val isHermesEnabledInProject = project.isHermesEnabled
3939
val isHermesEnabledInThisVariant =
@@ -54,7 +54,7 @@ internal fun Project.configureReactTasks(variant: Variant, config: ReactExtensio
5454
tasks.register("createBundle${targetName}JsAndAssets", BundleHermesCTask::class.java) {
5555
it.root.set(config.root)
5656
it.nodeExecutableAndArgs.set(config.nodeExecutableAndArgs)
57-
it.cliPath.set(cliPath)
57+
it.cliFile.set(cliFile)
5858
it.bundleCommand.set(config.bundleCommand)
5959
it.entryFile.set(detectedEntryFile(config))
6060
it.extraPackagerArgs.set(config.extraPackagerArgs)
@@ -69,7 +69,7 @@ internal fun Project.configureReactTasks(variant: Variant, config: ReactExtensio
6969
it.jsSourceMapsDir.set(jsSourceMapsDir)
7070
it.hermesCommand.set(config.hermesCommand)
7171
it.hermesFlags.set(config.hermesFlags)
72-
it.composeSourceMapsPath.set(config.composeSourceMapsPath)
72+
it.reactNativeDir.set(config.reactNativeDir)
7373
}
7474
variant.sources.res?.addGeneratedSourceDirectory(bundleTask, BundleHermesCTask::resourcesDir)
7575
variant.sources.assets?.addGeneratedSourceDirectory(bundleTask, BundleHermesCTask::jsBundleDir)

packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/tasks/BundleHermesCTask.kt

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,9 @@ abstract class BundleHermesCTask : DefaultTask() {
4242

4343
@get:Input abstract val nodeExecutableAndArgs: ListProperty<String>
4444

45-
@get:Input abstract val cliPath: Property<String>
45+
@get:InputFile abstract val cliFile: RegularFileProperty
4646

47-
@get:Input abstract val composeSourceMapsPath: Property<String>
47+
@get:Internal abstract val reactNativeDir: DirectoryProperty
4848

4949
@get:Input abstract val bundleCommand: Property<String>
5050

@@ -101,8 +101,12 @@ abstract class BundleHermesCTask : DefaultTask() {
101101
if (hermesFlags.get().contains("-output-source-map")) {
102102
val hermesTempSourceMapFile = File("$bytecodeFile.map")
103103
hermesTempSourceMapFile.moveTo(compilerSourceMap)
104+
105+
val reactNativeDir = reactNativeDir.get().asFile
106+
val composeScriptFile = File(reactNativeDir, "scripts/compose-source-maps.js")
104107
val composeSourceMapsCommand =
105-
getComposeSourceMapsCommand(packagerSourceMap, compilerSourceMap, outputSourceMap)
108+
getComposeSourceMapsCommand(
109+
composeScriptFile, packagerSourceMap, compilerSourceMap, outputSourceMap)
106110
runCommand(composeSourceMapsCommand)
107111
}
108112
}
@@ -132,7 +136,7 @@ abstract class BundleHermesCTask : DefaultTask() {
132136
windowsAwareCommandLine(
133137
buildList {
134138
addAll(nodeExecutableAndArgs.get())
135-
add(cliPath.get())
139+
add(cliFile.get().asFile.absolutePath)
136140
add(bundleCommand.get())
137141
add("--platform")
138142
add("android")
@@ -171,13 +175,14 @@ abstract class BundleHermesCTask : DefaultTask() {
171175
*hermesFlags.get().toTypedArray())
172176

173177
internal fun getComposeSourceMapsCommand(
178+
composeScript: File,
174179
packagerSourceMap: File,
175180
compilerSourceMap: File,
176181
outputSourceMap: File
177182
): List<Any> =
178183
windowsAwareCommandLine(
179184
*nodeExecutableAndArgs.get().toTypedArray(),
180-
composeSourceMapsPath.get(),
185+
composeScript.absolutePath,
181186
packagerSourceMap.toString(),
182187
compilerSourceMap.toString(),
183188
"-o",

packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/PathUtils.kt

Lines changed: 22 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -28,20 +28,16 @@ internal fun detectedEntryFile(config: ReactExtension): File =
2828
entryFile = config.entryFile.orNull?.asFile, reactRoot = config.root.get().asFile)
2929

3030
/**
31-
* Computes the CLI location for React Native. The Algo follows this order:
32-
* 1. The path provided by the `cliPath` config in the `reactApp` Gradle extension
31+
* Computes the CLI file for React Native. The Algo follows this order:
32+
* 1. The path provided by the `cliFile` config in the `react {}` Gradle extension
3333
* 2. The output of `node --print "require.resolve('react-native/cli');"` if not failing.
3434
* 3. The `node_modules/react-native/cli.js` file if exists
3535
* 4. Fails otherwise
3636
*/
37-
internal fun detectedCliPath(
38-
projectDir: File,
39-
config: ReactExtension,
40-
): String =
41-
detectCliPath(
42-
projectDir = projectDir,
43-
reactRoot = config.root.get().asFile,
44-
preconfiguredCliPath = config.cliPath.orNull)
37+
internal fun detectedCliFile(config: ReactExtension): File =
38+
detectCliFile(
39+
reactNativeRoot = config.root.get().asFile,
40+
preconfiguredCliFile = config.cliFile.asFile.orNull)
4541

4642
/**
4743
* Computes the `hermesc` command location. The Algo follows this order:
@@ -64,24 +60,11 @@ private fun detectEntryFile(entryFile: File?, reactRoot: File): File =
6460
else -> File(reactRoot, "index.js")
6561
}
6662

67-
private fun detectCliPath(
68-
projectDir: File,
69-
reactRoot: File,
70-
preconfiguredCliPath: String?
71-
): String {
63+
private fun detectCliFile(reactNativeRoot: File, preconfiguredCliFile: File?): File {
7264
// 1. preconfigured path
73-
if (preconfiguredCliPath != null) {
74-
val preconfiguredCliJsAbsolute = File(preconfiguredCliPath)
75-
if (preconfiguredCliJsAbsolute.exists()) {
76-
return preconfiguredCliJsAbsolute.absolutePath
77-
}
78-
val preconfiguredCliJsRelativeToReactRoot = File(reactRoot, preconfiguredCliPath)
79-
if (preconfiguredCliJsRelativeToReactRoot.exists()) {
80-
return preconfiguredCliJsRelativeToReactRoot.absolutePath
81-
}
82-
val preconfiguredCliJsRelativeToProject = File(projectDir, preconfiguredCliPath)
83-
if (preconfiguredCliJsRelativeToProject.exists()) {
84-
return preconfiguredCliJsRelativeToProject.absolutePath
65+
if (preconfiguredCliFile != null) {
66+
if (preconfiguredCliFile.exists()) {
67+
return preconfiguredCliFile
8568
}
8669
}
8770

@@ -91,27 +74,32 @@ private fun detectCliPath(
9174
.exec(
9275
arrayOf("node", "--print", "require.resolve('react-native/cli');"),
9376
emptyArray(),
94-
reactRoot)
77+
reactNativeRoot)
9578

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

9881
if (nodeProcessOutput.isNotEmpty()) {
9982
val nodeModuleCliJs = File(nodeProcessOutput)
10083
if (nodeModuleCliJs.exists()) {
101-
return nodeModuleCliJs.absolutePath
84+
return nodeModuleCliJs
10285
}
10386
}
10487

10588
// 3. cli.js in the root folder
106-
val rootCliJs = File(reactRoot, "node_modules/react-native/cli.js")
89+
val rootCliJs = File(reactNativeRoot, "node_modules/react-native/cli.js")
10790
if (rootCliJs.exists()) {
108-
return rootCliJs.absolutePath
91+
return rootCliJs
10992
}
11093

11194
error(
112-
"Couldn't determine CLI location. " +
113-
"Please set `project.react.cliPath` to the path of the react-native cli.js file. " +
114-
"This file typically resides in `node_modules/react-native/cli.js`")
95+
"""
96+
Couldn't determine CLI location!
97+
98+
Please set `react { cliFile = file(...) }` inside your
99+
build.gradle to the path of the react-native cli.js file.
100+
This file typically resides in `node_modules/react-native/cli.js`
101+
"""
102+
.trimIndent())
115103
}
116104

117105
/**

packages/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/tasks/BundleHermesCTaskTest.kt

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,6 @@ class BundleHermesCTaskTest {
8585
val task =
8686
createTestTask<BundleHermesCTask> {
8787
it.nodeExecutableAndArgs.set(listOf("node", "arg1", "arg2"))
88-
it.cliPath.set("../node_modules/react-native/cli.js")
89-
it.composeSourceMapsPath.set(
90-
"../node_modules/react-native/scripts/compose-source-maps.js")
9188
it.bundleCommand.set("bundle")
9289
it.bundleAssetName.set("myassetname")
9390
it.minifyEnabled.set(true)
@@ -99,10 +96,6 @@ class BundleHermesCTaskTest {
9996
}
10097

10198
assertEquals(listOf("node", "arg1", "arg2"), task.nodeExecutableAndArgs.get())
102-
assertEquals("../node_modules/react-native/cli.js", task.cliPath.get())
103-
assertEquals(
104-
"../node_modules/react-native/scripts/compose-source-maps.js",
105-
task.composeSourceMapsPath.get())
10699
assertEquals("bundle", task.bundleCommand.get())
107100
assertEquals("myassetname", task.bundleAssetName.get())
108101
assertTrue(task.minifyEnabled.get())
@@ -116,28 +109,34 @@ class BundleHermesCTaskTest {
116109
@Test
117110
fun bundleTask_filesInput_areSetCorrectly() {
118111
val entryFile = tempFolder.newFile("entry.js")
112+
val cliFile = tempFolder.newFile("cli.js")
119113
val jsBundleDir = tempFolder.newFolder("jsbundle")
120114
val resourcesDir = tempFolder.newFolder("resources")
121115
val jsIntermediateSourceMapsDir = tempFolder.newFolder("jsIntermediateSourceMaps")
122116
val jsSourceMapsDir = tempFolder.newFolder("jsSourceMaps")
123117
val bundleConfig = tempFolder.newFile("bundle.config")
118+
val reactNativeDir = tempFolder.newFolder("node_modules/react-native")
124119

125120
val task =
126121
createTestTask<BundleHermesCTask> {
127122
it.entryFile.set(entryFile)
123+
it.cliFile.set(cliFile)
128124
it.jsBundleDir.set(jsBundleDir)
129125
it.resourcesDir.set(resourcesDir)
130126
it.jsIntermediateSourceMapsDir.set(jsIntermediateSourceMapsDir)
131127
it.jsSourceMapsDir.set(jsSourceMapsDir)
132128
it.bundleConfig.set(bundleConfig)
129+
it.reactNativeDir.set(reactNativeDir)
133130
}
134131

135132
assertEquals(entryFile, task.entryFile.get().asFile)
133+
assertEquals(cliFile, task.cliFile.get().asFile)
136134
assertEquals(jsBundleDir, task.jsBundleDir.get().asFile)
137135
assertEquals(resourcesDir, task.resourcesDir.get().asFile)
138136
assertEquals(jsIntermediateSourceMapsDir, task.jsIntermediateSourceMapsDir.get().asFile)
139137
assertEquals(jsSourceMapsDir, task.jsSourceMapsDir.get().asFile)
140138
assertEquals(bundleConfig, task.bundleConfig.get().asFile)
139+
assertEquals(reactNativeDir, task.reactNativeDir.get().asFile)
141140
}
142141

143142
@Test
@@ -198,14 +197,15 @@ class BundleHermesCTaskTest {
198197
@Test
199198
fun getBundleCommand_returnsCorrectCommand() {
200199
val entryFile = tempFolder.newFile("index.js")
200+
val cliFile = tempFolder.newFile("cli.js")
201201
val bundleFile = tempFolder.newFile("bundle.js")
202202
val sourceMapFile = tempFolder.newFile("bundle.js.map")
203203
val resourcesDir = tempFolder.newFolder("res")
204204
val bundleConfig = tempFolder.newFile("bundle.config")
205205
val task =
206206
createTestTask<BundleHermesCTask> {
207207
it.nodeExecutableAndArgs.set(listOf("node", "arg1", "arg2"))
208-
it.cliPath.set("../node_modules/react-native/cli.js")
208+
it.cliFile.set(cliFile)
209209
it.bundleCommand.set("bundle")
210210
it.devEnabled.set(true)
211211
it.entryFile.set(entryFile)
@@ -220,7 +220,7 @@ class BundleHermesCTaskTest {
220220
assertEquals("node", bundleCommand[0])
221221
assertEquals("arg1", bundleCommand[1])
222222
assertEquals("arg2", bundleCommand[2])
223-
assertEquals("../node_modules/react-native/cli.js", bundleCommand[3])
223+
assertEquals(cliFile.absolutePath, bundleCommand[3])
224224
assertEquals("bundle", bundleCommand[4])
225225
assertEquals("--platform", bundleCommand[5])
226226
assertEquals("android", bundleCommand[6])
@@ -247,13 +247,14 @@ class BundleHermesCTaskTest {
247247
@Test
248248
fun getBundleCommand_withoutConfig_returnsCommandWithoutConfig() {
249249
val entryFile = tempFolder.newFile("index.js")
250+
val cliFile = tempFolder.newFile("cli.js")
250251
val bundleFile = tempFolder.newFile("bundle.js")
251252
val sourceMapFile = tempFolder.newFile("bundle.js.map")
252253
val resourcesDir = tempFolder.newFolder("res")
253254
val task =
254255
createTestTask<BundleHermesCTask> {
255256
it.nodeExecutableAndArgs.set(listOf("node", "arg1", "arg2"))
256-
it.cliPath.set("../node_modules/react-native/cli.js")
257+
it.cliFile.set(cliFile)
257258
it.bundleCommand.set("bundle")
258259
it.devEnabled.set(true)
259260
it.entryFile.set(entryFile)
@@ -291,21 +292,20 @@ class BundleHermesCTaskTest {
291292
val packagerMap = tempFolder.newFile("bundle.js.packager.map")
292293
val compilerMap = tempFolder.newFile("bundle.js.compiler.map")
293294
val outputMap = tempFolder.newFile("bundle.js.map")
295+
val reactNativeDir = tempFolder.newFolder("node_modules/react-native")
296+
val composeSourceMapsFile = File(reactNativeDir, "scripts/compose-source-maps.js")
294297
val task =
295298
createTestTask<BundleHermesCTask> {
296299
it.nodeExecutableAndArgs.set(listOf("node", "arg1", "arg2"))
297-
it.composeSourceMapsPath.set(
298-
"../node_modules/react-native/scripts/compose-source-maps.js")
299300
}
300301

301302
val composeSourcemapCommand =
302-
task.getComposeSourceMapsCommand(packagerMap, compilerMap, outputMap)
303+
task.getComposeSourceMapsCommand(composeSourceMapsFile, packagerMap, compilerMap, outputMap)
303304

304305
assertEquals("node", composeSourcemapCommand[0])
305306
assertEquals("arg1", composeSourcemapCommand[1])
306307
assertEquals("arg2", composeSourcemapCommand[2])
307-
assertEquals(
308-
"../node_modules/react-native/scripts/compose-source-maps.js", composeSourcemapCommand[3])
308+
assertEquals(composeSourceMapsFile.absolutePath, composeSourcemapCommand[3])
309309
assertEquals(packagerMap.absolutePath, composeSourcemapCommand[4])
310310
assertEquals(compilerMap.absolutePath, composeSourcemapCommand[5])
311311
assertEquals("-o", composeSourcemapCommand[6])

0 commit comments

Comments
 (0)