rnx-kit icon indicating copy to clipboard operation
rnx-kit copied to clipboard

Update Metro types in response to breaking changes in Metro's `resolver` configuration property

Open afoxman opened this issue 2 years ago • 4 comments

Background

@react-native-community/cli 8 moved from Metro 0.67 to 0.70. This brought in a breaking change from Metro. They changed the context parameter that is passed to the optional custom module resolver in Metro config (resolver property).

The context param (first argument) had previously been a read/write object with a resolveRequest property set to whatever custom resolver was in place (the function pointed to by resolver). When Metro made the call out to the custom resolver, it wouldn't change resolveRequest.

Our code has custom resolvers, and they sometimes need to call back into Metro to get the "default" resolution behavior. Metro needs the context, so to avoid infinite recursion, we would unhook resolveRequest from context and then put it back later.

With the breaking change from Metro, two things happened -- (i) context became a frozen (read-only) object, and (ii) the recursion detection was changed, effectively doing what we did by replacing resolveRequest before invoking any custom resolver.

Our code can no longer unhook and replace resolveRequest. JS will fail with a TypeError. To be compatible with old and new versions of Metro, we need to detect if resolveRequest is pointing at our resolver or Metro's resolver, and adjust as needed by making a copy of context rather than modifying it.

Timeline

Metro made this breaking change on 1/31/2022: https://github.com/facebook/metro/commit/d81d8877c05637eac2b4ea946a9fa1e8ae869b06. It shipped in version 0.68.

@react-native-community/cli updated from Metro 0.67 to 0.70 on 5/4/2022: https://github.com/react-native-community/cli/commit/65c5d02cd82704a0c0e78841d65f7da98db19342. This updated shipped in v8.0.0-alpha.5.

@react-native-community/cli-plugin-metro broke when alpha.5 was made, and was fixed in alpha.6 on 5/10/2022: https://github.com/react-native-community/cli/pull/1605.

RN 0.68.2, released yesterday, is still on Metro 0.67.x / CLI 7.x. RN 0.69-stable is on Metro 0.70.x and CLI 8.x, which means @rnx-kit customers going to RN 0.69 will break.

RN 0.69 is currently in the RC phase of being released as of 5/10/2022. It will be releasing soon (days, not weeks).

Proposed Fix

We have 2 packages which are impacted by these changes: @rnx-kit/metro-resolver-symlinks and @rnx-kit/metro-service.

@rnx-kit/metro-resolver-symlinks

src/index.ts: makeResolver(): Lift the anonymous arrow function out into a global function. Add logic to detect whether resolveRequest points to the global function, or Metro's resolve() function (from getMetroResolver()). If it points to ours, replace context with a copy of itself, setting resolveRequest to Metro's function.

@rnx-kit/metro-service

src/config.ts: reactNativePlatformResolver(): This code was copied from the CLI, before cli-plugin-metro was available to consume and use as its own package. I'd like to retire this logic, and use cli-plugin-metro, but we need to support a broad range of RN/CLI/Metro builds, spanning before and after this break. So, we should fix this the same way it was fixed in the CLI -- https://github.com/react-native-community/cli/commit/65c5d02cd82704a0c0e78841d65f7da98db19342.

afoxman avatar May 10 '22 21:05 afoxman

cc: @tido64 @kelset

afoxman avatar May 10 '22 21:05 afoxman

It will be releasing soon (days, not weeks).

quick note, it will be weeks before RN 0.69 reached 0.69.0. What will land soon is the next RC.

kelset avatar May 11 '22 09:05 kelset

Before we close this issue, we should also update the types: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/3625f7e63f834d0e37aa062127a903ca1ce8a3b8/types/metro-resolver/types.d.ts#L104-L109

tido64 avatar May 18 '22 07:05 tido64

(I didn't even realise that there are metro types on DT.. we probably need to fit those in the RN+TS conversation 🤦‍♂️)

kelset avatar May 18 '22 11:05 kelset

Types are being updated here: https://github.com/DefinitelyTyped/DefinitelyTyped/pull/64735

tido64 avatar Mar 14 '23 17:03 tido64