Skip to content

Commit 9b8f5f7

Browse files
committed
refactor: autolink transitive dependencies
1 parent 2204d35 commit 9b8f5f7

File tree

2 files changed

+93
-6
lines changed

2 files changed

+93
-6
lines changed

packages/cli-config/src/loadConfig.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {
1212
resolveNodeModuleDir,
1313
UnknownProjectError,
1414
} from '@react-native-community/cli-tools';
15-
import findDependencies from './findDependencies';
15+
import {collectDependencies, dedupeDependencies} from './resolveDependencies';
1616
import resolveReactNativePath from './resolveReactNativePath';
1717
import {
1818
readConfigFromDisk,
@@ -112,20 +112,24 @@ function loadConfig(projectRoot: string = findProjectRoot()): Config {
112112
return lazyProject;
113113
},
114114
};
115+
const deps = collectDependencies(projectRoot);
116+
const dedupedDeps = dedupeDependencies(deps);
115117

116118
const finalConfig = Array.from(
117-
new Set([
118-
...Object.keys(userConfig.dependencies),
119-
...findDependencies(projectRoot),
120-
]),
119+
new Set([...Object.keys(userConfig.dependencies), ...deps.keys()]),
121120
).reduce((acc: Config, dependencyName) => {
122121
const localDependencyRoot =
123122
userConfig.dependencies[dependencyName] &&
124123
userConfig.dependencies[dependencyName].root;
125124
try {
126125
let root =
127126
localDependencyRoot ||
128-
resolveNodeModuleDir(projectRoot, dependencyName);
127+
resolveNodeModuleDir(
128+
dedupedDeps.has(dependencyName)
129+
? dedupedDeps.get(dependencyName)!.path
130+
: projectRoot,
131+
dependencyName,
132+
);
129133
let config = readDependencyConfigFromDisk(root, dependencyName);
130134

131135
const isPlatform = Object.keys(config.platforms).length > 0;
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import path from 'path';
2+
import fs from 'fs-extra';
3+
4+
interface DependencyData {
5+
path: string;
6+
version: string;
7+
duplicates?: DependencyData[];
8+
}
9+
10+
export function collectDependencies(root: string): Map<string, DependencyData> {
11+
const dependencies = new Map<string, DependencyData>();
12+
13+
const checkDependency = (dependencyPath: string) => {
14+
const packageJsonPath = path.join(dependencyPath, 'package.json');
15+
const packageJson = require(packageJsonPath);
16+
17+
if (dependencies.has(packageJson.name)) {
18+
const dependency = dependencies.get(packageJson.name) as DependencyData;
19+
20+
if (
21+
dependencyPath !== dependency.path &&
22+
dependency.duplicates?.every(
23+
(duplicate) => duplicate.path !== dependencyPath,
24+
)
25+
) {
26+
dependencies.set(packageJson.name, {
27+
...dependency,
28+
duplicates: [
29+
...dependency.duplicates,
30+
{path: dependencyPath, version: packageJson.version},
31+
],
32+
});
33+
}
34+
35+
return;
36+
}
37+
38+
dependencies.set(packageJson.name, {
39+
path: dependencyPath,
40+
version: packageJson.version,
41+
duplicates: [],
42+
});
43+
44+
for (const dependency in {
45+
...packageJson.dependencies,
46+
...(root === dependencyPath ? packageJson.devDependencies : {}),
47+
}) {
48+
const depPath = path.join(dependencyPath, 'node_modules', dependency);
49+
const rootPath = path.join(root, 'node_modules', dependency);
50+
if (fs.existsSync(depPath)) {
51+
checkDependency(depPath);
52+
} else if (fs.existsSync(rootPath)) {
53+
checkDependency(rootPath);
54+
}
55+
}
56+
};
57+
58+
checkDependency(root);
59+
60+
return dependencies;
61+
}
62+
63+
export function dedupeDependencies(
64+
dependencies: Map<string, DependencyData>,
65+
): Map<string, DependencyData> {
66+
const latestVersions = new Map();
67+
Array.from(dependencies).forEach(([packageName, packageInfo]) => {
68+
if (packageInfo.duplicates!.length > 0) {
69+
const allVersions = [
70+
{path: packageInfo.path, version: packageInfo.version},
71+
...packageInfo.duplicates!,
72+
];
73+
74+
const findLatest = allVersions.reduce((highest, pkg) =>
75+
pkg.version.localeCompare(highest.version) === 1 ? pkg : highest,
76+
);
77+
78+
latestVersions.set(packageName, findLatest);
79+
}
80+
});
81+
82+
return latestVersions;
83+
}

0 commit comments

Comments
 (0)