expo-modules-autolinking 2.0.0 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -10,6 +10,18 @@
10
10
 
11
11
  ### 💡 Others
12
12
 
13
+ ## 2.0.2 — 2024-11-13
14
+
15
+ ### 🐛 Bug fixes
16
+
17
+ - Fixed autolinking when `react-native-config` doesn't specify local dependencies. ([#32841](https://github.com/expo/expo/pull/32841) by [@thespacemanatee](https://github.com/thespacemanatee))
18
+
19
+ ## 2.0.1 — 2024-11-13
20
+
21
+ ### 💡 Others
22
+
23
+ - Added local project dependencies support to `react-native-config` autolinking. ([#32821](https://github.com/expo/expo/pull/32821) by [@kudo](https://github.com/kudo))
24
+
13
25
  ## 2.0.0 — 2024-11-11
14
26
 
15
27
  _This version does not introduce any user-facing changes._
@@ -1,5 +1,5 @@
1
- import type { RNConfigCommandOptions, RNConfigDependency, RNConfigReactNativeAppProjectConfig, RNConfigReactNativeProjectConfig, RNConfigResult } from './reactNativeConfig.types';
2
1
  import type { SupportedPlatform } from '../types';
2
+ import type { RNConfigCommandOptions, RNConfigDependency, RNConfigReactNativeAppProjectConfig, RNConfigReactNativeProjectConfig, RNConfigResult } from './reactNativeConfig.types';
3
3
  /**
4
4
  * Create config for react-native core autolinking.
5
5
  */
@@ -6,17 +6,20 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.resolveAppProjectConfigAsync = exports.resolveDependencyConfigAsync = exports.findDependencyRootsAsync = exports.createReactNativeConfigAsync = void 0;
7
7
  const promises_1 = __importDefault(require("fs/promises"));
8
8
  const path_1 = __importDefault(require("path"));
9
+ const utils_1 = require("../autolinking/utils");
10
+ const fileUtils_1 = require("../fileUtils");
9
11
  const androidResolver_1 = require("./androidResolver");
10
12
  const config_1 = require("./config");
11
13
  const iosResolver_1 = require("./iosResolver");
12
- const utils_1 = require("../autolinking/utils");
13
- const fileUtils_1 = require("../fileUtils");
14
14
  /**
15
15
  * Create config for react-native core autolinking.
16
16
  */
17
17
  async function createReactNativeConfigAsync({ platform, projectRoot, searchPaths, }) {
18
18
  const projectConfig = await (0, config_1.loadConfigAsync)(projectRoot);
19
- const dependencyRoots = await findDependencyRootsAsync(projectRoot, searchPaths);
19
+ const dependencyRoots = {
20
+ ...(await findDependencyRootsAsync(projectRoot, searchPaths)),
21
+ ...findProjectLocalDependencyRoots(projectConfig),
22
+ };
20
23
  const reactNativePath = dependencyRoots['react-native'];
21
24
  const dependencyConfigs = await Promise.all(Object.entries(dependencyRoots).map(async ([name, packageRoot]) => {
22
25
  const config = await resolveDependencyConfigAsync(platform, name, packageRoot, projectConfig);
@@ -61,6 +64,21 @@ async function findDependencyRootsAsync(projectRoot, searchPaths) {
61
64
  return results;
62
65
  }
63
66
  exports.findDependencyRootsAsync = findDependencyRootsAsync;
67
+ /**
68
+ * Find local dependencies that specified in the `react-native.config.js` file.
69
+ */
70
+ function findProjectLocalDependencyRoots(projectConfig) {
71
+ if (!projectConfig?.dependencies) {
72
+ return {};
73
+ }
74
+ const results = {};
75
+ for (const [name, config] of Object.entries(projectConfig.dependencies)) {
76
+ if (typeof config.root === 'string') {
77
+ results[name] = config.root;
78
+ }
79
+ }
80
+ return results;
81
+ }
64
82
  async function resolveDependencyConfigAsync(platform, name, packageRoot, projectConfig) {
65
83
  const libraryConfig = await (0, config_1.loadConfigAsync)(packageRoot);
66
84
  const reactNativeConfig = {
@@ -1 +1 @@
1
- {"version":3,"file":"reactNativeConfig.js","sourceRoot":"","sources":["../../src/reactNativeConfig/reactNativeConfig.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from 'fs/promises';\nimport path from 'path';\n\nimport {\n findGradleAndManifestAsync,\n parsePackageNameAsync,\n resolveDependencyConfigImplAndroidAsync,\n} from './androidResolver';\nimport { loadConfigAsync } from './config';\nimport { resolveDependencyConfigImplIosAsync } from './iosResolver';\nimport type {\n RNConfigCommandOptions,\n RNConfigDependency,\n RNConfigReactNativeAppProjectConfig,\n RNConfigReactNativeLibraryConfig,\n RNConfigReactNativeProjectConfig,\n RNConfigResult,\n} from './reactNativeConfig.types';\nimport { getIsolatedModulesPath } from '../autolinking/utils';\nimport { fileExistsAsync } from '../fileUtils';\nimport type { SupportedPlatform } from '../types';\n\n/**\n * Create config for react-native core autolinking.\n */\nexport async function createReactNativeConfigAsync({\n platform,\n projectRoot,\n searchPaths,\n}: RNConfigCommandOptions): Promise<RNConfigResult> {\n const projectConfig = await loadConfigAsync<RNConfigReactNativeProjectConfig>(projectRoot);\n const dependencyRoots = await findDependencyRootsAsync(projectRoot, searchPaths);\n const reactNativePath = dependencyRoots['react-native'];\n\n const dependencyConfigs = await Promise.all(\n Object.entries(dependencyRoots).map(async ([name, packageRoot]) => {\n const config = await resolveDependencyConfigAsync(platform, name, packageRoot, projectConfig);\n return [name, config];\n })\n );\n const dependencyResults = Object.fromEntries<RNConfigDependency>(\n dependencyConfigs.filter(([, config]) => config != null) as Iterable<\n [string, RNConfigDependency]\n >\n );\n const projectData = await resolveAppProjectConfigAsync(projectRoot, platform);\n return {\n root: projectRoot,\n reactNativePath,\n dependencies: dependencyResults,\n project: projectData,\n };\n}\n\n/**\n * Find all dependencies and their directories from the project.\n */\nexport async function findDependencyRootsAsync(\n projectRoot: string,\n searchPaths: string[]\n): Promise<Record<string, string>> {\n const packageJson = JSON.parse(await fs.readFile(path.join(projectRoot, 'package.json'), 'utf8'));\n const dependencies = [\n ...Object.keys(packageJson.dependencies ?? {}),\n ...Object.keys(packageJson.devDependencies ?? {}),\n ];\n\n const results: Record<string, string> = {};\n // `searchPathSet` can be mutated to discover all \"isolated modules groups\", when using isolated modules\n const searchPathSet = new Set(searchPaths);\n\n for (const name of dependencies) {\n for (const searchPath of searchPathSet) {\n const packageConfigPath = path.resolve(searchPath, name, 'package.json');\n if (await fileExistsAsync(packageConfigPath)) {\n const packageRoot = path.dirname(packageConfigPath);\n results[name] = packageRoot;\n\n const maybeIsolatedModulesPath = getIsolatedModulesPath(packageRoot, name);\n if (maybeIsolatedModulesPath) {\n searchPathSet.add(maybeIsolatedModulesPath);\n }\n break;\n }\n }\n }\n\n return results;\n}\n\nexport async function resolveDependencyConfigAsync(\n platform: SupportedPlatform,\n name: string,\n packageRoot: string,\n projectConfig: RNConfigReactNativeProjectConfig | null\n): Promise<RNConfigDependency | null> {\n const libraryConfig = await loadConfigAsync<RNConfigReactNativeLibraryConfig>(packageRoot);\n const reactNativeConfig = {\n ...libraryConfig?.dependency,\n ...projectConfig?.dependencies?.[name],\n };\n\n if (Object.keys(libraryConfig?.platforms ?? {}).length > 0) {\n // Package defines platforms would be a platform host package.\n // The rnc-cli will skip this package.\n return null;\n }\n if (name === 'react-native') {\n // Starting from version 0.76, the `react-native` package only defines platforms\n // when @react-native-community/cli-platform-android/ios is installed.\n // Therefore, we need to manually filter it out.\n return null;\n }\n\n let platformData = null;\n if (platform === 'android') {\n platformData = await resolveDependencyConfigImplAndroidAsync(\n packageRoot,\n reactNativeConfig.platforms?.android\n );\n } else if (platform === 'ios') {\n platformData = await resolveDependencyConfigImplIosAsync(\n packageRoot,\n reactNativeConfig.platforms?.ios\n );\n }\n if (!platformData) {\n return null;\n }\n return {\n root: packageRoot,\n name,\n platforms: {\n [platform]: platformData,\n },\n };\n}\n\nexport async function resolveAppProjectConfigAsync(\n projectRoot: string,\n platform: SupportedPlatform\n): Promise<RNConfigReactNativeAppProjectConfig> {\n if (platform === 'android') {\n const androidDir = path.join(projectRoot, 'android');\n const { gradle, manifest } = await findGradleAndManifestAsync({ androidDir, isLibrary: false });\n if (gradle == null || manifest == null) {\n return {};\n }\n const packageName = await parsePackageNameAsync(androidDir, manifest, gradle);\n\n return {\n android: {\n packageName: packageName ?? '',\n sourceDir: path.join(projectRoot, 'android'),\n },\n };\n }\n\n if (platform === 'ios') {\n return {\n ios: {\n sourceDir: path.join(projectRoot, 'ios'),\n },\n };\n }\n\n return {};\n}\n"]}
1
+ {"version":3,"file":"reactNativeConfig.js","sourceRoot":"","sources":["../../src/reactNativeConfig/reactNativeConfig.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from 'fs/promises';\nimport path from 'path';\n\nimport { getIsolatedModulesPath } from '../autolinking/utils';\nimport { fileExistsAsync } from '../fileUtils';\nimport type { SupportedPlatform } from '../types';\nimport {\n findGradleAndManifestAsync,\n parsePackageNameAsync,\n resolveDependencyConfigImplAndroidAsync,\n} from './androidResolver';\nimport { loadConfigAsync } from './config';\nimport { resolveDependencyConfigImplIosAsync } from './iosResolver';\nimport type {\n RNConfigCommandOptions,\n RNConfigDependency,\n RNConfigReactNativeAppProjectConfig,\n RNConfigReactNativeLibraryConfig,\n RNConfigReactNativeProjectConfig,\n RNConfigResult,\n} from './reactNativeConfig.types';\n\n/**\n * Create config for react-native core autolinking.\n */\nexport async function createReactNativeConfigAsync({\n platform,\n projectRoot,\n searchPaths,\n}: RNConfigCommandOptions): Promise<RNConfigResult> {\n const projectConfig = await loadConfigAsync<RNConfigReactNativeProjectConfig>(projectRoot);\n const dependencyRoots = {\n ...(await findDependencyRootsAsync(projectRoot, searchPaths)),\n ...findProjectLocalDependencyRoots(projectConfig),\n };\n const reactNativePath = dependencyRoots['react-native'];\n\n const dependencyConfigs = await Promise.all(\n Object.entries(dependencyRoots).map(async ([name, packageRoot]) => {\n const config = await resolveDependencyConfigAsync(platform, name, packageRoot, projectConfig);\n return [name, config];\n })\n );\n const dependencyResults = Object.fromEntries<RNConfigDependency>(\n dependencyConfigs.filter(([, config]) => config != null) as Iterable<\n [string, RNConfigDependency]\n >\n );\n const projectData = await resolveAppProjectConfigAsync(projectRoot, platform);\n return {\n root: projectRoot,\n reactNativePath,\n dependencies: dependencyResults,\n project: projectData,\n };\n}\n\n/**\n * Find all dependencies and their directories from the project.\n */\nexport async function findDependencyRootsAsync(\n projectRoot: string,\n searchPaths: string[]\n): Promise<Record<string, string>> {\n const packageJson = JSON.parse(await fs.readFile(path.join(projectRoot, 'package.json'), 'utf8'));\n const dependencies = [\n ...Object.keys(packageJson.dependencies ?? {}),\n ...Object.keys(packageJson.devDependencies ?? {}),\n ];\n\n const results: Record<string, string> = {};\n // `searchPathSet` can be mutated to discover all \"isolated modules groups\", when using isolated modules\n const searchPathSet = new Set(searchPaths);\n\n for (const name of dependencies) {\n for (const searchPath of searchPathSet) {\n const packageConfigPath = path.resolve(searchPath, name, 'package.json');\n if (await fileExistsAsync(packageConfigPath)) {\n const packageRoot = path.dirname(packageConfigPath);\n results[name] = packageRoot;\n\n const maybeIsolatedModulesPath = getIsolatedModulesPath(packageRoot, name);\n if (maybeIsolatedModulesPath) {\n searchPathSet.add(maybeIsolatedModulesPath);\n }\n break;\n }\n }\n }\n\n return results;\n}\n\n/**\n * Find local dependencies that specified in the `react-native.config.js` file.\n */\nfunction findProjectLocalDependencyRoots(\n projectConfig: RNConfigReactNativeProjectConfig | null\n): Record<string, string> {\n if (!projectConfig?.dependencies) {\n return {};\n }\n const results: Record<string, string> = {};\n for (const [name, config] of Object.entries(projectConfig.dependencies)) {\n if (typeof config.root === 'string') {\n results[name] = config.root;\n }\n }\n return results;\n}\n\nexport async function resolveDependencyConfigAsync(\n platform: SupportedPlatform,\n name: string,\n packageRoot: string,\n projectConfig: RNConfigReactNativeProjectConfig | null\n): Promise<RNConfigDependency | null> {\n const libraryConfig = await loadConfigAsync<RNConfigReactNativeLibraryConfig>(packageRoot);\n const reactNativeConfig = {\n ...libraryConfig?.dependency,\n ...projectConfig?.dependencies?.[name],\n };\n\n if (Object.keys(libraryConfig?.platforms ?? {}).length > 0) {\n // Package defines platforms would be a platform host package.\n // The rnc-cli will skip this package.\n return null;\n }\n if (name === 'react-native') {\n // Starting from version 0.76, the `react-native` package only defines platforms\n // when @react-native-community/cli-platform-android/ios is installed.\n // Therefore, we need to manually filter it out.\n return null;\n }\n\n let platformData = null;\n if (platform === 'android') {\n platformData = await resolveDependencyConfigImplAndroidAsync(\n packageRoot,\n reactNativeConfig.platforms?.android\n );\n } else if (platform === 'ios') {\n platformData = await resolveDependencyConfigImplIosAsync(\n packageRoot,\n reactNativeConfig.platforms?.ios\n );\n }\n if (!platformData) {\n return null;\n }\n return {\n root: packageRoot,\n name,\n platforms: {\n [platform]: platformData,\n },\n };\n}\n\nexport async function resolveAppProjectConfigAsync(\n projectRoot: string,\n platform: SupportedPlatform\n): Promise<RNConfigReactNativeAppProjectConfig> {\n if (platform === 'android') {\n const androidDir = path.join(projectRoot, 'android');\n const { gradle, manifest } = await findGradleAndManifestAsync({ androidDir, isLibrary: false });\n if (gradle == null || manifest == null) {\n return {};\n }\n const packageName = await parsePackageNameAsync(androidDir, manifest, gradle);\n\n return {\n android: {\n packageName: packageName ?? '',\n sourceDir: path.join(projectRoot, 'android'),\n },\n };\n }\n\n if (platform === 'ios') {\n return {\n ios: {\n sourceDir: path.join(projectRoot, 'ios'),\n },\n };\n }\n\n return {};\n}\n"]}
@@ -59,6 +59,7 @@ export interface RNConfigResult {
59
59
  export type RNConfigReactNativePlatformsConfigAndroid = any;
60
60
  export type RNConfigReactNativePlatformsConfigIos = any;
61
61
  interface RNConfigReactNativePlatformsConfig {
62
+ root?: string;
62
63
  platforms?: {
63
64
  android?: RNConfigReactNativePlatformsConfigAndroid;
64
65
  ios?: RNConfigReactNativePlatformsConfigIos;
@@ -68,7 +69,7 @@ interface RNConfigReactNativePlatformsConfig {
68
69
  * The `react-native.config.js` config from projectRoot.
69
70
  */
70
71
  export interface RNConfigReactNativeProjectConfig {
71
- dependencies: Record<string, RNConfigReactNativePlatformsConfig>;
72
+ dependencies?: Record<string, RNConfigReactNativePlatformsConfig>;
72
73
  }
73
74
  /**
74
75
  * The `react-native.config.js` config from library packageRoot.
@@ -1 +1 @@
1
- {"version":3,"file":"reactNativeConfig.types.js","sourceRoot":"","sources":["../../src/reactNativeConfig/reactNativeConfig.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { SupportedPlatform } from '../types';\n\n/**\n * Options for 'react-native-config' command.\n */\nexport interface RNConfigCommandOptions {\n platform: SupportedPlatform;\n projectRoot: string;\n searchPaths: string[];\n}\n\n/**\n * Dependency configuration for Android platform.\n */\nexport interface RNConfigDependencyAndroid {\n sourceDir: string;\n packageImportPath: string;\n packageInstance: string;\n dependencyConfiguration?: string;\n buildTypes: string[];\n libraryName?: string | null;\n componentDescriptors?: string[] | null;\n cmakeListsPath?: string | null;\n cxxModuleCMakeListsModuleName?: string | null;\n cxxModuleCMakeListsPath?: string | null;\n cxxModuleHeaderName?: string | null;\n}\n\n/**\n * Dependency configuration for iOS platform.\n */\nexport interface RNConfigDependencyIos {\n podspecPath: string;\n version: string;\n configurations: string[];\n scriptPhases: any[];\n}\n\n/**\n * Dependency configuration.\n */\nexport interface RNConfigDependency {\n root: string;\n name: string;\n platforms: {\n android?: RNConfigDependencyAndroid;\n ios?: RNConfigDependencyIos;\n };\n}\n\n/**\n * Result of 'react-native-config' command.\n */\nexport interface RNConfigResult {\n root: string;\n reactNativePath: string;\n dependencies: Record<string, RNConfigDependency>;\n project: {\n ios?: {\n sourceDir: string;\n };\n };\n}\n\nexport type RNConfigReactNativePlatformsConfigAndroid = any;\nexport type RNConfigReactNativePlatformsConfigIos = any;\n\ninterface RNConfigReactNativePlatformsConfig {\n platforms?: {\n android?: RNConfigReactNativePlatformsConfigAndroid;\n ios?: RNConfigReactNativePlatformsConfigIos;\n };\n}\n\n/**\n * The `react-native.config.js` config from projectRoot.\n */\nexport interface RNConfigReactNativeProjectConfig {\n dependencies: Record<string, RNConfigReactNativePlatformsConfig>;\n}\n\n/**\n * The `react-native.config.js` config from library packageRoot.\n */\nexport interface RNConfigReactNativeLibraryConfig {\n dependency?: RNConfigReactNativePlatformsConfig;\n platforms?: any;\n}\n\nexport type RNConfigReactNativeConfig =\n | RNConfigReactNativeProjectConfig\n | RNConfigReactNativeLibraryConfig;\n\n/**\n * The `project` config represents the app project configuration.\n */\nexport interface RNConfigReactNativeAppProjectConfig {\n android?: {\n sourceDir: string;\n packageName: string;\n };\n ios?: {\n sourceDir: string;\n };\n}\n"]}
1
+ {"version":3,"file":"reactNativeConfig.types.js","sourceRoot":"","sources":["../../src/reactNativeConfig/reactNativeConfig.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { SupportedPlatform } from '../types';\n\n/**\n * Options for 'react-native-config' command.\n */\nexport interface RNConfigCommandOptions {\n platform: SupportedPlatform;\n projectRoot: string;\n searchPaths: string[];\n}\n\n/**\n * Dependency configuration for Android platform.\n */\nexport interface RNConfigDependencyAndroid {\n sourceDir: string;\n packageImportPath: string;\n packageInstance: string;\n dependencyConfiguration?: string;\n buildTypes: string[];\n libraryName?: string | null;\n componentDescriptors?: string[] | null;\n cmakeListsPath?: string | null;\n cxxModuleCMakeListsModuleName?: string | null;\n cxxModuleCMakeListsPath?: string | null;\n cxxModuleHeaderName?: string | null;\n}\n\n/**\n * Dependency configuration for iOS platform.\n */\nexport interface RNConfigDependencyIos {\n podspecPath: string;\n version: string;\n configurations: string[];\n scriptPhases: any[];\n}\n\n/**\n * Dependency configuration.\n */\nexport interface RNConfigDependency {\n root: string;\n name: string;\n platforms: {\n android?: RNConfigDependencyAndroid;\n ios?: RNConfigDependencyIos;\n };\n}\n\n/**\n * Result of 'react-native-config' command.\n */\nexport interface RNConfigResult {\n root: string;\n reactNativePath: string;\n dependencies: Record<string, RNConfigDependency>;\n project: {\n ios?: {\n sourceDir: string;\n };\n };\n}\n\nexport type RNConfigReactNativePlatformsConfigAndroid = any;\nexport type RNConfigReactNativePlatformsConfigIos = any;\n\ninterface RNConfigReactNativePlatformsConfig {\n root?: string;\n platforms?: {\n android?: RNConfigReactNativePlatformsConfigAndroid;\n ios?: RNConfigReactNativePlatformsConfigIos;\n };\n}\n\n/**\n * The `react-native.config.js` config from projectRoot.\n */\nexport interface RNConfigReactNativeProjectConfig {\n dependencies?: Record<string, RNConfigReactNativePlatformsConfig>;\n}\n\n/**\n * The `react-native.config.js` config from library packageRoot.\n */\nexport interface RNConfigReactNativeLibraryConfig {\n dependency?: RNConfigReactNativePlatformsConfig;\n platforms?: any;\n}\n\nexport type RNConfigReactNativeConfig =\n | RNConfigReactNativeProjectConfig\n | RNConfigReactNativeLibraryConfig;\n\n/**\n * The `project` config represents the app project configuration.\n */\nexport interface RNConfigReactNativeAppProjectConfig {\n android?: {\n sourceDir: string;\n packageName: string;\n };\n ios?: {\n sourceDir: string;\n };\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-modules-autolinking",
3
- "version": "2.0.0",
3
+ "version": "2.0.2",
4
4
  "description": "Scripts that autolink Expo modules.",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -48,5 +48,5 @@
48
48
  "require-from-string": "^2.0.2",
49
49
  "resolve-from": "^5.0.0"
50
50
  },
51
- "gitHead": "8f2567ad26ca782cd2d7ab7fa77a34979e2b4e01"
51
+ "gitHead": "c4999f5aa407155a170830a0fa17e3e3ca1fcbee"
52
52
  }
@@ -1,6 +1,9 @@
1
1
  import fs from 'fs/promises';
2
2
  import path from 'path';
3
3
 
4
+ import { getIsolatedModulesPath } from '../autolinking/utils';
5
+ import { fileExistsAsync } from '../fileUtils';
6
+ import type { SupportedPlatform } from '../types';
4
7
  import {
5
8
  findGradleAndManifestAsync,
6
9
  parsePackageNameAsync,
@@ -16,9 +19,6 @@ import type {
16
19
  RNConfigReactNativeProjectConfig,
17
20
  RNConfigResult,
18
21
  } from './reactNativeConfig.types';
19
- import { getIsolatedModulesPath } from '../autolinking/utils';
20
- import { fileExistsAsync } from '../fileUtils';
21
- import type { SupportedPlatform } from '../types';
22
22
 
23
23
  /**
24
24
  * Create config for react-native core autolinking.
@@ -29,7 +29,10 @@ export async function createReactNativeConfigAsync({
29
29
  searchPaths,
30
30
  }: RNConfigCommandOptions): Promise<RNConfigResult> {
31
31
  const projectConfig = await loadConfigAsync<RNConfigReactNativeProjectConfig>(projectRoot);
32
- const dependencyRoots = await findDependencyRootsAsync(projectRoot, searchPaths);
32
+ const dependencyRoots = {
33
+ ...(await findDependencyRootsAsync(projectRoot, searchPaths)),
34
+ ...findProjectLocalDependencyRoots(projectConfig),
35
+ };
33
36
  const reactNativePath = dependencyRoots['react-native'];
34
37
 
35
38
  const dependencyConfigs = await Promise.all(
@@ -88,6 +91,24 @@ export async function findDependencyRootsAsync(
88
91
  return results;
89
92
  }
90
93
 
94
+ /**
95
+ * Find local dependencies that specified in the `react-native.config.js` file.
96
+ */
97
+ function findProjectLocalDependencyRoots(
98
+ projectConfig: RNConfigReactNativeProjectConfig | null
99
+ ): Record<string, string> {
100
+ if (!projectConfig?.dependencies) {
101
+ return {};
102
+ }
103
+ const results: Record<string, string> = {};
104
+ for (const [name, config] of Object.entries(projectConfig.dependencies)) {
105
+ if (typeof config.root === 'string') {
106
+ results[name] = config.root;
107
+ }
108
+ }
109
+ return results;
110
+ }
111
+
91
112
  export async function resolveDependencyConfigAsync(
92
113
  platform: SupportedPlatform,
93
114
  name: string,
@@ -66,6 +66,7 @@ export type RNConfigReactNativePlatformsConfigAndroid = any;
66
66
  export type RNConfigReactNativePlatformsConfigIos = any;
67
67
 
68
68
  interface RNConfigReactNativePlatformsConfig {
69
+ root?: string;
69
70
  platforms?: {
70
71
  android?: RNConfigReactNativePlatformsConfigAndroid;
71
72
  ios?: RNConfigReactNativePlatformsConfigIos;
@@ -76,7 +77,7 @@ interface RNConfigReactNativePlatformsConfig {
76
77
  * The `react-native.config.js` config from projectRoot.
77
78
  */
78
79
  export interface RNConfigReactNativeProjectConfig {
79
- dependencies: Record<string, RNConfigReactNativePlatformsConfig>;
80
+ dependencies?: Record<string, RNConfigReactNativePlatformsConfig>;
80
81
  }
81
82
 
82
83
  /**