Skip to content

Commit

Permalink
fix: resolve @react-native-community/cli-* packages transitively
Browse files Browse the repository at this point in the history
  • Loading branch information
tido64 committed Sep 25, 2023
1 parent f567d9a commit 311b744
Show file tree
Hide file tree
Showing 15 changed files with 83 additions and 44 deletions.
5 changes: 5 additions & 0 deletions .changeset/afraid-adults-hear.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@rnx-kit/cli": patch
---

Resolve correct `@react-native-community/cli-clean` instance through `react-native`
5 changes: 5 additions & 0 deletions .changeset/fluffy-dots-kick.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@rnx-kit/tools-node": minor
---

Added function for resolving a dependency chain
5 changes: 5 additions & 0 deletions .changeset/proud-kiwis-heal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@rnx-kit/jest-preset": patch
---

Resolve correct `@react-native-community/cli` instance through `react-native`
5 changes: 5 additions & 0 deletions .changeset/tricky-jokes-explain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@rnx-kit/metro-service": patch
---

Resolve correct `@react-native-community/cli-plugin-metro` instance through `react-native`
12 changes: 0 additions & 12 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,22 +41,10 @@
"readline": "^1.3.0"
},
"peerDependencies": {
"@react-native-community/cli": ">=5.0.1",
"@react-native-community/cli-clean": ">=8.0.0",
"@react-native-community/cli-server-api": ">=5.0.1",
"jest-cli": ">=26.0",
"react-native": ">=0.64"
},
"peerDependenciesMeta": {
"@react-native-community/cli": {
"optional": true
},
"@react-native-community/cli-clean": {
"optional": true
},
"@react-native-community/cli-server-api": {
"optional": true
},
"jest-cli": {
"optional": true
},
Expand Down
3 changes: 2 additions & 1 deletion packages/cli/src/clean.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import * as fs from "fs-extra";
import ora from "ora";
import * as os from "os";
import * as path from "path";
import { requireExternal } from "./serve/external";

type Args = {
include?: string;
Expand All @@ -30,7 +31,7 @@ export async function rnxClean(

const spinner = ora();
try {
require.resolve("@react-native-community/cli-clean");
requireExternal("@react-native-community/cli-clean");
spinner.warn(
"`rnx-clean` has been upstreamed to `@react-native-community/cli`. Please use `npx react-native clean` instead."
);
Expand Down
20 changes: 16 additions & 4 deletions packages/cli/src/serve/external.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import { resolveDependencyChain } from "@rnx-kit/tools-node/package";
import type { CliServerApi, CoreDevMiddleware } from "./types";

type CliClean = typeof import("@react-native-community/cli-clean");

type ExternalModule =
| "@react-native-community/cli-clean"
| "@react-native-community/cli-server-api"
| "@react-native/dev-middleware";

function friendlyRequire<T>(...modules: string[]): T {
try {
const modulePath = modules.reduce((startDir, module) => {
return require.resolve(module, { paths: [startDir] });
}, process.cwd());
const modulePath = resolveDependencyChain(modules);
return require(modulePath) as T;
} catch (_) {
const module = modules[modules.length - 1];
Expand All @@ -22,6 +24,10 @@ function friendlyRequire<T>(...modules: string[]): T {
}
}

export function requireExternal(
module: "@react-native-community/cli-clean"
): CliClean;

export function requireExternal(
module: "@react-native-community/cli-server-api"
): CliServerApi;
Expand All @@ -32,8 +38,14 @@ export function requireExternal(

export function requireExternal(
module: ExternalModule
): CliServerApi | CoreDevMiddleware {
): CliClean | CliServerApi | CoreDevMiddleware {
switch (module) {
case "@react-native-community/cli-clean":
return friendlyRequire<CliClean>(
"react-native",
"@react-native-community/cli",
"@react-native-community/cli-clean"
);
case "@react-native-community/cli-server-api":
return friendlyRequire<CliServerApi>(
"react-native",
Expand Down
5 changes: 1 addition & 4 deletions packages/jest-preset/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,14 @@
"dependencies": {
"@babel/preset-env": "^7.0.0",
"@babel/preset-typescript": "^7.0.0",
"@rnx-kit/tools-node": "^2.0.1",
"find-up": "^5.0.0"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0",
"@react-native-community/cli": ">=4.10",
"react-native": "^0.0.0-0 || >=0.63"
},
"peerDependenciesMeta": {
"@react-native-community/cli": {
"optional": true
},
"react-native": {
"optional": true
}
Expand Down
22 changes: 14 additions & 8 deletions packages/jest-preset/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,19 @@ function getTargetPlatform(defaultPlatform) {
return getReactNativePlatformPath();
}

const { resolveDependencyChain } = require("@rnx-kit/tools-node/package");

/** @type {() => CLIConfig} */
const loadConfig =
// @ts-ignore could not find a declaration file
require("@react-native-community/cli").loadConfig ||
// @ts-ignore could not find a declaration file
require("@react-native-community/cli/build/tools/config").default;
const loadConfig = (() => {
const rnCliPath = resolveDependencyChain([
"react-native",
"@react-native-community/cli",
]);
return (
require(rnCliPath).loadConfig ||
require(`${rnCliPath}/build/tools/config`).default
);
})();

const { platforms } = loadConfig();
const targetPlatformConfig = platforms[defaultPlatform];
Expand All @@ -95,13 +102,12 @@ function getTargetPlatform(defaultPlatform) {

// `npmPackageName` is unset if target platform is in core.
const { npmPackageName } = targetPlatformConfig;
const projectRoot = { paths: [process.cwd()] };
return [
defaultPlatform,
npmPackageName
? path.dirname(
require.resolve(`${npmPackageName}/package.json`, {
paths: [process.cwd()],
})
require.resolve(`${npmPackageName}/package.json`, projectRoot)
)
: undefined,
];
Expand Down
1 change: 1 addition & 0 deletions packages/metro-service/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"dependencies": {
"@rnx-kit/console": "^1.0.0",
"@rnx-kit/tools-language": "^2.0.0",
"@rnx-kit/tools-node": "^2.0.1",
"chalk": "^4.1.0",
"node-fetch": "^2.6.7"
},
Expand Down
11 changes: 8 additions & 3 deletions packages/metro-service/src/config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { Config as CLIConfig } from "@react-native-community/cli-types";
import { resolveDependencyChain } from "@rnx-kit/tools-node/package";
import type { ConfigT, InputConfigT } from "metro-config";
import { loadConfig } from "metro-config";
import type {
Expand Down Expand Up @@ -168,9 +169,13 @@ function getDefaultConfigProvider(
}

try {
const cliPluginMetro = require.resolve(
"@react-native-community/cli-plugin-metro",
options
const cliPluginMetro = resolveDependencyChain(
[
"react-native",
"@react-native-community/cli",
"@react-native-community/cli-plugin-metro",
],
projectRoot
);
const { getDefaultConfig } = require(cliPluginMetro);

Expand Down
1 change: 1 addition & 0 deletions packages/tools-node/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import * as pathTools from "@rnx-kit/tools-node/path";
| package | `findPackageDir(startDir)` | Find the parent directory of the nearest `package.json` manifest file. Search upward through all parent directories. |
| package | `parsePackageRef(r)` | Parse a package reference string. An example reference is the `name` property found in `package.json`. |
| package | `readPackage(pkgPath)` | Read a `package.json` manifest from a file. |
| package | `resolveDependencyChain(chain, startDir)` | Resolve the path to a dependency given a chain of dependencies leading up to it. |
| package | `writePackage(pkgPath, manifest, space)` | Write a `package.json` manifest to a file. |
| path | `normalizePath(p)` | Normalize the separators in a path, converting each backslash ('\\') to a foreward slash ('/'). |

Expand Down
1 change: 1 addition & 0 deletions packages/tools-node/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export {
findPackageDir,
parsePackageRef,
readPackage,
resolveDependencyChain,
writePackage,
} from "./package";
export type {
Expand Down
17 changes: 17 additions & 0 deletions packages/tools-node/src/package.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,3 +206,20 @@ export function findPackageDependencyDir(
? path.resolve(path.dirname(packageDir), fs.readlinkSync(packageDir))
: packageDir;
}

/**
* Resolve the path to a dependency given a chain of dependencies leading up to
* it.
* @param chain Chain of dependencies leading up to the target dependency.
* @param startDir Optional starting directory for the search. If not given, the current directory is used.
* @returns Path to the final dependency's directory.
*/
export function resolveDependencyChain(
chain: string[],
startDir = process.cwd()
) {
return chain.reduce((startDir, module) => {
const p = require.resolve(`${module}/package.json`, { paths: [startDir] });
return path.dirname(p);
}, startDir);
}
14 changes: 2 additions & 12 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3511,18 +3511,9 @@ __metadata:
type-fest: ^4.0.0
typescript: ^5.0.0
peerDependencies:
"@react-native-community/cli": ">=5.0.1"
"@react-native-community/cli-clean": ">=8.0.0"
"@react-native-community/cli-server-api": ">=5.0.1"
jest-cli: ">=26.0"
react-native: ">=0.64"
peerDependenciesMeta:
"@react-native-community/cli":
optional: true
"@react-native-community/cli-clean":
optional: true
"@react-native-community/cli-server-api":
optional: true
jest-cli:
optional: true
react-native:
Expand Down Expand Up @@ -3666,6 +3657,7 @@ __metadata:
"@jest/types": ^29.2.1
"@rnx-kit/eslint-config": "*"
"@rnx-kit/scripts": "*"
"@rnx-kit/tools-node": ^2.0.1
"@types/node": ^18.0.0
eslint: ^8.0.0
find-up: ^5.0.0
Expand All @@ -3676,11 +3668,8 @@ __metadata:
typescript: ^5.0.0
peerDependencies:
"@babel/core": ^7.0.0-0
"@react-native-community/cli": ">=4.10"
react-native: ^0.0.0-0 || >=0.63
peerDependenciesMeta:
"@react-native-community/cli":
optional: true
react-native:
optional: true
languageName: unknown
Expand Down Expand Up @@ -3861,6 +3850,7 @@ __metadata:
"@rnx-kit/console": ^1.0.0
"@rnx-kit/scripts": "*"
"@rnx-kit/tools-language": ^2.0.0
"@rnx-kit/tools-node": ^2.0.1
"@types/node": ^18.0.0
"@types/node-fetch": ^2.6.5
chalk: ^4.1.0
Expand Down

0 comments on commit 311b744

Please sign in to comment.