Skip to content

Commit 951fb12

Browse files
acoates-mstido64
andauthored
metro-resolver-symlinks support for metro 0.82 (#3920)
* Support for metro 0.82 * docs(changeset): Add support for metro 0.82 * Update packages/metro-resolver-symlinks/src/utils/metro.ts Co-authored-by: Tommy Nguyen <[email protected]> * review feedback --------- Co-authored-by: Tommy Nguyen <[email protected]>
1 parent dcfadad commit 951fb12

File tree

2 files changed

+58
-26
lines changed

2 files changed

+58
-26
lines changed

.changeset/chilly-rivers-fail.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+
Add support for metro 0.82

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

Lines changed: 53 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ function fileExists(path: string): boolean {
2525
function importMetroModule(path: string) {
2626
const modulePath = findMetroPath() + path;
2727
try {
28-
return require(modulePath);
28+
const mod = require(modulePath);
29+
return mod.default ?? mod;
2930
} catch (_) {
3031
throw new Error(
3132
`Cannot find '${modulePath}'. This probably means that ` +
@@ -76,16 +77,22 @@ export function shouldEnableRetryResolvingFromDisk({
7677
return disableWithReason(
7778
`has not been tested with '${RETRY_FROM_DISK_FLAG}'`
7879
);
79-
} else if (v > 81) {
80-
return disableWithReason(
81-
`should no longer need '${RETRY_FROM_DISK_FLAG}'`
82-
);
8380
}
8481
}
8582

8683
return Boolean(experimental_retryResolvingFromDisk);
8784
}
8885

86+
function computeSha1(filePath: string): string {
87+
// Paths generated by pnpm setups include version numbers and/or hashes
88+
if (filePath.includes(".pnpm-store") || filePath.includes(".store")) {
89+
return filePath;
90+
}
91+
92+
const stat = fs.lstatSync(filePath);
93+
return filePath + "|" + stat.mtime.toISOString();
94+
}
95+
8996
/**
9097
* Monkey-patches Metro to not use HasteFS as the only source for module
9198
* resolution.
@@ -158,31 +165,51 @@ export function patchMetro(options: Options): void {
158165

159166
// Since we will be resolving files outside of `watchFolders`, their hashes
160167
// will not be found. We'll return the `filePath` as they should be unique.
161-
DependencyGraph.prototype.orig_getSha1 = DependencyGraph.prototype.getSha1;
162-
DependencyGraph.prototype.getSha1 = function (filePath: string): string {
163-
try {
164-
return this.orig_getSha1(filePath);
165-
} catch (e) {
166-
// `ReferenceError` will always be thrown when Metro encounters a file
167-
// that does not exist in the Haste map.
168-
// In metro 0.81 (https://github.com/facebook/metro/pull/1435)
169-
// this was changed to a standard `Error` - so verify the message
170-
if (
171-
e instanceof ReferenceError ||
172-
(e instanceof Error && e.message.startsWith("Failed to get the SHA-1"))
173-
) {
174-
// Paths generated by pnpm setups include version numbers and/or hashes
175-
if (filePath.includes(".pnpm-store") || filePath.includes(".store")) {
176-
return filePath;
168+
// getSha1 was replaced with getOrComputeSha1 in metro 0.82 (https://github.com/facebook/metro/commit/e667aa3acd594d795bbab45c45107e7bc6322303)
169+
if (DependencyGraph.prototype.getSha1) {
170+
DependencyGraph.prototype.orig_getSha1 = DependencyGraph.prototype.getSha1;
171+
DependencyGraph.prototype.getSha1 = function (filePath: string): string {
172+
try {
173+
return this.orig_getSha1(filePath);
174+
} catch (e) {
175+
// `ReferenceError` will always be thrown when Metro encounters a file
176+
// that does not exist in the Haste map.
177+
// In metro 0.81 (https://github.com/facebook/metro/pull/1435)
178+
// this was changed to a standard `Error` - so verify the message
179+
if (
180+
e instanceof ReferenceError ||
181+
(e instanceof Error &&
182+
e.message.startsWith("Failed to get the SHA-1"))
183+
) {
184+
return computeSha1(filePath);
177185
}
178186

179-
const stat = fs.lstatSync(filePath);
180-
return filePath + "|" + stat.mtime.toISOString();
187+
throw e;
181188
}
189+
};
190+
}
182191

183-
throw e;
184-
}
185-
};
192+
// getSha1 was replaced with getOrComputeSha1 in metro 0.82 (https://github.com/facebook/metro/commit/e667aa3acd594d795bbab45c45107e7bc6322303)
193+
if (DependencyGraph.prototype.getOrComputeSha1) {
194+
DependencyGraph.prototype.orig_getOrComputeSha1 =
195+
DependencyGraph.prototype.getOrComputeSha1;
196+
DependencyGraph.prototype.getOrComputeSha1 = async function (
197+
filePath: string
198+
): Promise<{ content?: Buffer; sha1: string }> {
199+
try {
200+
return await this.orig_getOrComputeSha1(filePath);
201+
} catch (e) {
202+
if (
203+
e instanceof Error &&
204+
e.message.startsWith("Failed to get the SHA-1")
205+
) {
206+
return { sha1: computeSha1(filePath) };
207+
}
208+
209+
throw e;
210+
}
211+
};
212+
}
186213

187214
// We need to patch `_processSingleAssetRequest` because it calls
188215
// `Assets.getAsset`, and `Assets.getAsset` checks whether the asset lives

0 commit comments

Comments
 (0)