From 6fe32dc6a55a900aefe1df77d1e6b4205640c455 Mon Sep 17 00:00:00 2001 From: k6G52m4Dz75W <74605402+k6G52m4Dz75W@users.noreply.github.com> Date: Thu, 3 Sep 2026 23:56:38 +0800 Subject: [PATCH] fix(android): patch @expo/cli to resolve relative --entry-file against project root SDK 54's @expo/cli (54.0.23) fails to bundle a release APK when react-native's gradle plugin passes a relative --entry-file on Windows inside a pnpm monorepo: resolveRealEntryFilePath() returns the relative path unchanged, so Metro resolves it against the monorepo root instead of the app dir and fails with 'Unable to resolve module ./index.js from /'. Mirror the upstream fix from expo/expo#44414 (SDK 55, not backported): resolve a relative entry-file to an absolute path against the project root before the existing realpath handling. Verified end-to-end: gradle assembleRelease now produces a signed APK; relative and absolute --entry-file both bundle. Applied via pnpm patch (patches/@expo__cli@54.0.23.patch) so pnpm install re-applies it automatically. --- package.json | 3 ++- patches/@expo__cli@54.0.23.patch | 32 ++++++++++++++++++++++++++++++++ pnpm-lock.yaml | 7 +++++-- 3 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 patches/@expo__cli@54.0.23.patch diff --git a/package.json b/package.json index e596e59c8..4c4b12064 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,8 @@ }, "patchedDependencies": { "@langchain/core": "patches/@langchain__core.patch", - "react-native-track-player@4.1.2": "patches/react-native-track-player@4.1.2.patch" + "react-native-track-player@4.1.2": "patches/react-native-track-player@4.1.2.patch", + "@expo/cli@54.0.23": "patches/@expo__cli@54.0.23.patch" } }, "packageManager": "pnpm@9.15.0" diff --git a/patches/@expo__cli@54.0.23.patch b/patches/@expo__cli@54.0.23.patch new file mode 100644 index 000000000..588827a38 --- /dev/null +++ b/patches/@expo__cli@54.0.23.patch @@ -0,0 +1,32 @@ +diff --git a/build/src/utils/filePath.js b/build/src/utils/filePath.js +index 68eed166a8061d9a2488a454aeaa13487416d53b..6ff1ae8b6a1a37c722aa0e71182d2835a5eca9a6 100644 +--- a/build/src/utils/filePath.js ++++ b/build/src/utils/filePath.js +@@ -23,6 +23,13 @@ function _fs() { + }; + return data; + } ++function _path() { ++ const data = /*#__PURE__*/ _interop_require_default(require("path")); ++ _path = function() { ++ return data; ++ }; ++ return data; ++} + function _interop_require_default(obj) { + return obj && obj.__esModule ? obj : { + default: obj +@@ -30,6 +37,13 @@ function _interop_require_default(obj) { + } + const REGEXP_REPLACE_SLASHES = /\\/g; + function resolveRealEntryFilePath(projectRoot, entryFile) { ++ // A relative --entry-file is relative to the project root (not the server ++ // root). Resolve it to an absolute path first so Metro gets a correct ++ // mainModuleName in pnpm monorepos on Windows. Mirrors the fix in ++ // expo/expo#44414 (SDK 55), not backported to SDK 54. ++ if (!_path().default.isAbsolute(entryFile)) { ++ entryFile = _path().default.resolve(process.cwd(), projectRoot, entryFile); ++ } + if (projectRoot.startsWith('/private/var') && entryFile.startsWith('/var')) { + return _fs().default.realpathSync(entryFile); + } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8aed804ec..f22d8a4e6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10,6 +10,9 @@ overrides: '@types/react': 19.1.17 patchedDependencies: + '@expo/cli@54.0.23': + hash: xnnprts3wgwjemoo7wbqe2veuy + path: patches/@expo__cli@54.0.23.patch '@langchain/core': hash: fsq4dynshckwono4lsk3t4tbui path: patches/@langchain__core.patch @@ -11025,7 +11028,7 @@ snapshots: dependencies: uuid: 8.3.2 - '@expo/cli@54.0.23(expo@54.0.33(@babel/core@7.29.0)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(graphql@16.8.1)(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))': + '@expo/cli@54.0.23(patch_hash=xnnprts3wgwjemoo7wbqe2veuy)(expo@54.0.33(@babel/core@7.29.0)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(graphql@16.8.1)(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))': dependencies: '@0no-co/graphql.web': 1.2.0(graphql@16.8.1) '@expo/code-signing-certificates': 0.0.6 @@ -15798,7 +15801,7 @@ snapshots: expo@54.0.33(@babel/core@7.29.0)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0): dependencies: '@babel/runtime': 7.28.6 - '@expo/cli': 54.0.23(expo@54.0.33(@babel/core@7.29.0)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(graphql@16.8.1)(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0)) + '@expo/cli': 54.0.23(patch_hash=xnnprts3wgwjemoo7wbqe2veuy)(expo@54.0.33(@babel/core@7.29.0)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(graphql@16.8.1)(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0)) '@expo/config': 12.0.13 '@expo/config-plugins': 54.0.4 '@expo/devtools': 0.1.8(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)