Skip to content

Commit f145c88

Browse files
authored
fix(metro-resolver-symlinks): add support for 0.82+ (#3627)
1 parent c8a796d commit f145c88

File tree

3 files changed

+48
-27
lines changed

3 files changed

+48
-27
lines changed

.changeset/eight-wasps-wonder.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@rnx-kit/metro-resolver-symlinks": patch
3+
---
4+
5+
`experimental_retryResolvingFromDisk` should no longer be necessary as of 0.82+

packages/metro-resolver-symlinks/src/utils/enhancedResolveHelpers.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { expandPlatformExtensions } from "@rnx-kit/tools-react-native/platform";
22
import * as path from "node:path";
33
import type { ResolutionContextCompat } from "../types";
4+
import { isPackageExportsEnabled } from "./metro";
45

56
export function getFromDir({
67
originModulePath,
@@ -9,16 +10,15 @@ export function getFromDir({
910
}
1011

1112
export function makeEnhancedResolveOptions(
12-
{
13-
extraNodeModules,
14-
mainFields,
15-
sourceExts,
16-
unstable_conditionNames,
17-
unstable_enablePackageExports,
18-
}: ResolutionContextCompat,
13+
context: ResolutionContextCompat,
1914
platform = "common"
2015
) {
16+
const { extraNodeModules, mainFields, sourceExts, unstable_conditionNames } =
17+
context;
18+
2119
const extensions = sourceExts.map((ext) => `.${ext}`);
20+
const enablePackageExports = isPackageExportsEnabled(context);
21+
2222
return {
2323
// Map Metro's `context.extraNodeModules` to Webpack's `resolve.alias`.
2424
// Metro's implementation is a subset of Webpack's. See:
@@ -30,13 +30,13 @@ export function makeEnhancedResolveOptions(
3030
// Add `require` to handle packages that are missing `default`
3131
// conditional. See
3232
// https://github.com/webpack/enhanced-resolve/issues/313
33-
conditionNames: unstable_enablePackageExports
33+
conditionNames: enablePackageExports
3434
? unstable_conditionNames.slice()
3535
: ["require", "node"],
3636

3737
// Unless `unstable_enablePackageExports` is enabled, disable exports
3838
// map as it currently takes precedence over the `react-native` field.
39-
...(unstable_enablePackageExports ? undefined : { exportsFields: [] }),
39+
...(enablePackageExports ? undefined : { exportsFields: [] }),
4040

4141
extensions:
4242
platform === "common"

packages/metro-resolver-symlinks/src/utils/metro.ts

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,16 @@ import {
66
import * as fs from "node:fs";
77
import * as path from "node:path";
88
import * as url from "node:url";
9-
import type { Options } from "../types";
9+
import type { Options, ResolutionContextCompat } from "../types";
10+
11+
const RETRY_FROM_DISK_FLAG = "experimental_retryResolvingFromDisk";
12+
13+
function disableWithReason(reason: string) {
14+
warn(
15+
`This version of Metro ${reason}; if you still want to enable it, set it to 'force'.`
16+
);
17+
return false;
18+
}
1019

1120
function fileExists(path: string): boolean {
1221
const stat = fs.statSync(path, { throwIfNoEntry: false });
@@ -20,10 +29,10 @@ function importMetroModule(path: string) {
2029
} catch (_) {
2130
throw new Error(
2231
`Cannot find '${modulePath}'. This probably means that ` +
23-
"'experimental_retryResolvingFromDisk' is not compatible with the " +
24-
"version of 'metro' that you are currently using. Please update to " +
25-
"the latest version and try again. If the issue still persists after " +
26-
"the update, please file a bug at " +
32+
`'${RETRY_FROM_DISK_FLAG}' is not compatible with the version of ` +
33+
"'metro' that you are currently using. Please update to the latest " +
34+
"version and try again. If the issue still persists after the " +
35+
"update, please file a bug at " +
2736
"https://github.com/microsoft/rnx-kit/issues."
2837
);
2938
}
@@ -41,9 +50,13 @@ const metroVersion = (() => {
4150
};
4251
})();
4352

44-
function supportsRetryResolvingFromDisk(): boolean {
45-
const v = metroVersion();
46-
return v >= 64 && v <= 81;
53+
export function isPackageExportsEnabled({
54+
unstable_enablePackageExports,
55+
}: Pick<ResolutionContextCompat, "unstable_enablePackageExports">): boolean {
56+
// https://github.com/facebook/metro/releases/tag/v0.82.0
57+
return unstable_enablePackageExports == null
58+
? metroVersion() >= 82
59+
: unstable_enablePackageExports;
4760
}
4861

4962
export function supportsSymlinks(): boolean {
@@ -53,18 +66,21 @@ export function supportsSymlinks(): boolean {
5366

5467
export function shouldEnableRetryResolvingFromDisk({
5568
experimental_retryResolvingFromDisk,
56-
}: Options): boolean {
69+
}: Pick<Options, typeof RETRY_FROM_DISK_FLAG>): boolean {
5770
if (
5871
experimental_retryResolvingFromDisk &&
59-
experimental_retryResolvingFromDisk !== "force" &&
60-
!supportsRetryResolvingFromDisk()
72+
experimental_retryResolvingFromDisk !== "force"
6173
) {
62-
warn(
63-
"The version of Metro you're using has not been tested with " +
64-
"`experimental_retryResolvingFromDisk`. If you still want to enable " +
65-
"it, please set it to 'force'."
66-
);
67-
return false;
74+
const v = metroVersion();
75+
if (v < 64) {
76+
return disableWithReason(
77+
`has not been tested with '${RETRY_FROM_DISK_FLAG}'`
78+
);
79+
} else if (v > 81) {
80+
return disableWithReason(
81+
`should no longer need '${RETRY_FROM_DISK_FLAG}'`
82+
);
83+
}
6884
}
6985

7086
return Boolean(experimental_retryResolvingFromDisk);
@@ -102,7 +118,7 @@ export function patchMetro(options: Options): void {
102118
return;
103119
}
104120

105-
info(`experimental_retryResolvingFromDisk: Patching '${findMetroPath()}'`);
121+
info(`${RETRY_FROM_DISK_FLAG}: Patching '${findMetroPath()}'`);
106122

107123
const DependencyGraph = importMetroModule("/src/node-haste/DependencyGraph");
108124

0 commit comments

Comments
 (0)