Skip to content

Commit 6615eb3

Browse files
TMaszkograbbou
andauthored
feat(android): added custom scope method for android dependencies (react-native-community#1430)
* feat: added customScope key to the dependency config type * feat: added ability to define config inside project.android * chore: updated docs * chore: typo * chore: revert `,` * Update projects.md * Update projects.md * chore: rename * Revert "chore: rename" This reverts commit 58d3d23. * chore: rename Co-authored-by: Mike Grabowski <[email protected]>
1 parent 83a370f commit 6615eb3

File tree

7 files changed

+64
-6
lines changed

7 files changed

+64
-6
lines changed

docs/dependencies.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ type DependencyParamsAndroidT = {
6767
packageImportPath?: string;
6868
packageInstance?: string;
6969
buildTypes?: string[];
70+
dependencyConfiguration?: string;
7071
};
7172
```
7273

@@ -135,6 +136,11 @@ For settings applicable on other platforms, please consult their respective docu
135136

136137
An array of build variants or flavors which will include the dependency. If the array is empty, your dependency will be included in all build types. If you're working on a helper library that should only be included in development, such as a replacement for the React Native development menu, you should set this to `['debug']` to avoid shipping the library in a release build. For more details, see [`build variants`](https://developer.android.com/studio/build/build-variants#dependencies).
137138

139+
### platforms.android.dependencyConfiguration
140+
141+
A string that defines which method other than `implementation` do you want to use
142+
for autolinking inside `build.gradle` i.e: `'embed project(path: ":$dependencyName", configuration: "default")',` - `"dependencyName` will be replaced by the actual package's name. You can achieve the same result by directly defining this key per `dependency` _(without placeholder)_ and it will have higher priority than this option.
143+
138144
### assets
139145

140146
An array of assets folders to glob for files to link.

docs/platforms.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,10 @@ type PlatformConfig<ProjectParams, ProjectConfig, DependencyConfig> = {
6060

6161
### npmPackageName
6262

63-
Returns the name of the npm package that should be used as the source for react-native JS code for platforms that provide platform specific overrides to core JS files. This causes the default metro config to redirect imports of react-native to another package based when bundling for that platform. The package specified should provide a complete react-native implementation for that platform.
63+
Returns the name of the npm package that should be used as the source for react-native JS code for platforms that provide platform specific overrides to core JS files. This causes the default metro config to redirect imports of react-native to another package based when bundling for that platform. The package specified should provide a complete react-native implementation for that platform.
6464

6565
If this property is not specified, it is assumed that the code in core `react-native` works for the platform.
6666

67-
6867
### projectConfig
6968

7069
Returns a project configuration for a given platform or `null`, when no project found. This is later used inside `linkConfig` to perform linking and unlinking.
@@ -112,6 +111,7 @@ type ProjectConfigAndroidT = {
112111
packageName: string;
113112
packageFolder: string;
114113
appName: string;
114+
dependencyConfiguration?: string;
115115
};
116116
```
117117

@@ -145,6 +145,7 @@ type DependencyConfigAndroidT = {
145145
packageInstance: string;
146146
manifestPath: string;
147147
packageName: string;
148+
dependencyConfiguration?: string;
148149
};
149150
```
150151

docs/projects.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ type AndroidProjectParams = {
7777
assetsPath?: string;
7878
buildGradlePath?: string;
7979
appName?: string; // A name of the app in the Android `sourceDir`, equivalent to Gradle project name. By default it's `app`.
80+
dependencyConfiguration?: string;
8081
};
8182

8283
type IOSProjectParams = {
@@ -121,6 +122,25 @@ module.exports = {
121122

122123
in order to disable linking of React Native WebView on iOS.
123124

125+
or you could set:
126+
127+
```js
128+
module.exports = {
129+
dependencies: {
130+
'react-native-brownfield': {
131+
platforms: {
132+
android: {
133+
dependencyConfiguration:
134+
'embed project(path: ":react-native-brownfield-bridge", configuration: "default")',
135+
},
136+
},
137+
},
138+
},
139+
};
140+
```
141+
142+
in order to use something else than `implementation` _(default scope method)_
143+
124144
Another use-case would be supporting local libraries that are not discoverable for autolinking, since they're not part of your `dependencies` or `devDependencies`:
125145

126146
```js

packages/cli-types/src/android.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export interface AndroidProjectConfig {
1111
packageName: string;
1212
packageFolder: string;
1313
appName: string;
14+
dependencyConfiguration?: string;
1415
}
1516

1617
export type AndroidProjectParams = Partial<AndroidProjectConfig>;
@@ -22,6 +23,7 @@ export interface AndroidDependencyConfig {
2223
packageInstance: string;
2324
manifestPath: string;
2425
packageName: string;
26+
dependencyConfiguration?: string;
2527
buildTypes: string[];
2628
}
2729

packages/cli/src/tools/config/schema.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ export const dependencyConfig = t
7575
manifestPath: t.string(),
7676
packageImportPath: t.string(),
7777
packageInstance: t.string(),
78+
dependencyConfiguration: t.string(),
7879
buildTypes: t.array().items(t.string()).default([]),
7980
})
8081
.default({}),
@@ -140,6 +141,7 @@ export const projectConfig = t
140141
folder: t.string(),
141142
packageImportPath: t.string(),
142143
packageInstance: t.string(),
144+
dependencyConfiguration: t.string(),
143145
buildTypes: t.array().items(t.string()).default([]),
144146
})
145147
.allow(null),
@@ -178,6 +180,7 @@ export const projectConfig = t
178180
assetsPath: t.string(),
179181
buildGradlePath: t.string(),
180182
appName: t.string(),
183+
dependencyConfiguration: t.string(),
181184
})
182185
.default({}),
183186
})

packages/platform-android/native_modules.gradle

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,16 +105,24 @@ class ReactNativeModules {
105105
void addReactNativeModuleDependencies(Project appProject) {
106106
reactNativeModules.forEach { reactNativeModule ->
107107
def nameCleansed = reactNativeModule["nameCleansed"]
108+
def dependencyConfiguration = reactNativeModule["dependencyConfiguration"]
108109
appProject.dependencies {
109110
if (reactNativeModulesBuildVariants.containsKey(nameCleansed)) {
110111
reactNativeModulesBuildVariants
111112
.get(nameCleansed)
112-
.forEach { buildVariant ->
113-
"${buildVariant}Implementation" project(path: ":${nameCleansed}")
113+
.forEach { buildVariant ->
114+
if(dependencyConfiguration != null) {
115+
"${buildVariant}${dependencyConfiguration}"
116+
} else {
117+
"${buildVariant}Implementation" project(path: ":${nameCleansed}")
118+
}
114119
}
115120
} else {
116-
// TODO(salakar): are other dependency scope methods such as `api` required?
117-
implementation project(path: ":${nameCleansed}")
121+
if(dependencyConfiguration != null) {
122+
"${dependencyConfiguration}"
123+
} else {
124+
implementation project(path: ":${nameCleansed}")
125+
}
118126
}
119127
}
120128
}
@@ -248,6 +256,8 @@ class ReactNativeModules {
248256
throw new Exception("React Native CLI failed to determine Android project configuration. This is likely due to misconfiguration. Config output:\n${json.toMapString()}")
249257
}
250258

259+
def engine = new groovy.text.SimpleTemplateEngine()
260+
251261
dependencies.each { name, value ->
252262
def platformsConfig = value["platforms"];
253263
def androidConfig = platformsConfig["android"]
@@ -265,6 +275,15 @@ class ReactNativeModules {
265275
if (!androidConfig["buildTypes"].isEmpty()) {
266276
reactNativeModulesBuildVariants.put(nameCleansed, androidConfig["buildTypes"])
267277
}
278+
if(androidConfig.containsKey("dependencyConfiguration")) {
279+
reactNativeModuleConfig.put("dependencyConfiguration", androidConfig["dependencyConfiguration"])
280+
} else if (project.containsKey("dependencyConfiguration")) {
281+
def bindings = ["dependencyName": nameCleansed]
282+
def template = engine.createTemplate(project["dependencyConfiguration"]).make(bindings)
283+
284+
reactNativeModuleConfig.put("dependencyConfiguration", template.toString())
285+
}
286+
268287
this.logger.trace("${LOG_PREFIX}'${name}': ${reactNativeModuleConfig.toMapString()}")
269288

270289
reactNativeModules.add(reactNativeModuleConfig)

packages/platform-android/src/config/index.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@ export function projectConfig(
8484
userConfig.buildGradlePath || 'build.gradle',
8585
);
8686

87+
const dependencyConfiguration =
88+
userConfig.dependencyConfiguration;
89+
8790
return {
8891
sourceDir,
8992
isFlat,
@@ -97,6 +100,7 @@ export function projectConfig(
97100
packageName,
98101
packageFolder,
99102
appName,
103+
dependencyConfiguration,
100104
};
101105
}
102106

@@ -155,12 +159,15 @@ export function dependencyConfig(
155159
userConfig.packageInstance || `new ${packageClassName}()`;
156160

157161
const buildTypes = userConfig.buildTypes || [];
162+
const dependencyConfiguration =
163+
userConfig.dependencyConfiguration;
158164

159165
return {
160166
sourceDir,
161167
folder: root,
162168
packageImportPath,
163169
packageInstance,
164170
buildTypes,
171+
dependencyConfiguration,
165172
};
166173
}

0 commit comments

Comments
 (0)