metro icon indicating copy to clipboard operation
metro copied to clipboard

Unable to resolve "metro-runtime/private/modules/HMRClient" from "node_modules/@expo/metro/metro-runtime/modules/HMRClient.js"

Open shiowwj opened this issue 3 months ago • 5 comments

I am upgrading my expo sdk from 53 to 54 and getting the error when bundling for Web

Web Bundling failed 1318ms node_modules/expo-router/_error.js (391 modules) Unable to resolve "metro-runtime/private/modules/HMRClient" from "node_modules/@expo/metro/metro-runtime/modules/HMRClient.js"

1 | module.exports = require("metro-runtime/private/modules/HMRClient"); | ^ 2 | 3 |

Import stack:

node_modules/@expo/metro/metro-runtime/modules/HMRClient.js | import "metro-runtime/private/modules/HMRClient"

node_modules/expo/src/async-require/hmr.ts | import "@expo/metro/metro-runtime/modules/HMRClient"

node_modules/expo/src/async-require/loadBundle.ts | import "./hmr"

node_modules/expo/src/async-require/buildAsyncRequire.ts | import "./loadBundle"

node_modules/expo/src/async-require/index.ts | import "./buildAsyncRequire"

node_modules/expo/src/Expo.fx.web.tsx | import "./async-require"

node_modules/expo/src/Expo.ts | import "./Expo.fx"

node_modules/expo-router/build/utils/splash.js | import "expo"

node_modules/expo-router/build/views/Splash.js | import "../utils/splash"

node_modules/expo-router/build/global-state/router-store.js | import "../views/Splash"

node_modules/expo-router/build/global-state/routing.js | import "./router-store"

node_modules/expo-router/build/imperative-api.js | import "./global-state/routing"

node_modules/expo-router/build/hooks.js | import "./imperative-api"

node_modules/expo-router/build/exports.js | import "./hooks"

node_modules/expo-router/build/index.js | import "./exports"

src/app/(protected)/(tabs)/_layout.tsx | import "expo-router"

src/app (require.context)

shiowwj avatar Sep 16 '25 08:09 shiowwj

Not the best solution, but I've unblocked myself with this patch:

diff --git a/src/async-require/hmr.ts b/src/async-require/hmr.ts
index 975d3512b3128391a83aa20f97ab8b7b59861cd4..f0dd7a906768bfb93a10fdaa8a635eb5c2984dfc 100644
--- a/src/async-require/hmr.ts
+++ b/src/async-require/hmr.ts
@@ -8,7 +8,7 @@
  * Based on this but with web support:
  * https://github.com/facebook/react-native/blob/086714b02b0fb838dee5a66c5bcefe73b53cf3df/Libraries/Utilities/HMRClient.js
  */
-import MetroHMRClient from '@expo/metro/metro-runtime/modules/HMRClient';
+import MetroHMRClient from 'metro-runtime/src/modules/HMRClient';
 import prettyFormat, { plugins } from 'pretty-format';
 import { DeviceEventEmitter } from 'react-native';

Its basically simple revert from this change: https://github.com/expo/expo/commit/2b5b77d75de3a09d2418d6f001d4bb414a791794#diff-04475f5a949f3fc858e19ca508a00f4648ee80f57c6b0d9ca2154339fa26452bL12

sakhnyuk avatar Sep 16 '25 10:09 sakhnyuk

Suffering from this aswell. Horrible bug.

jslindgit avatar Sep 17 '25 17:09 jslindgit

This bug should be reported to expo.

csheppard avatar Sep 18 '25 09:09 csheppard

CC @kitten, @byCedric

robhogan avatar Sep 18 '25 09:09 robhogan

Usually this happens because of a resolution in your package.json. @expo/metro is pinned to a specific version of metro-runtime (and all other metro dependencies). This cannot be overridden and Expo is now tied to a specific version of Metro and won't use "outside" Metro dependencies any longer, which is facilitated by us only depending on Metro via the @expo/metro package.

This means, if you see this error, your @expo/metro > metro-runtime dependency chain is broken. This is either caused by:

  • invalid node modules installations
  • or; an invalid resolution/override in your package.json which should've been removed as part of the SDK 54 upgrade

Edit: There might be one exception to this when package.json:exports support is explicitly disabled in the Metro config. We currently don't encourage this to be disabled globally rather than adding a granular resolution function, but we'll issue a fix for this in @expo/metro.

That said, if you added config.resolver.unstable_enablePackageExports = false to your config, please consider removing this.

kitten avatar Sep 18 '25 09:09 kitten