Skip to content

fix(android): 打补丁让 @expo/cli 相对 --entry-file 按项目根解析(SDK 54 Windows + pnpm monorepo release 构建) - #758

Open
k6G52m4Dz75W wants to merge 1 commit into
codedogQBY:mainfrom
k6G52m4Dz75W:fix/expo-cli-relative-entryfile-upstream
Open

fix(android): 打补丁让 @expo/cli 相对 --entry-file 按项目根解析(SDK 54 Windows + pnpm monorepo release 构建)#758
k6G52m4Dz75W wants to merge 1 commit into
codedogQBY:mainfrom
k6G52m4Dz75W:fix/expo-cli-relative-entryfile-upstream

Conversation

@k6G52m4Dz75W

Copy link
Copy Markdown
Contributor

问题

Windows + pnpm monorepo 环境下,用 Expo SDK 54 构建 Android release APK 会失败。gradle assembleReleasecreateBundleReleaseJsAndAssets 阶段必现报错:

Error: Unable to resolve module ./index.js from E:\<repo-root>\.: 

Metro 把 monorepo 根目录当作解析基准,而不是 app 目录。原因是 react-native 的 gradle 插件在 Windows 上传递相对路径--entry-file(其 File.cliPath() 在 macOS/Linux 返回绝对路径、Windows 返回相对路径),而 SDK 54 的 @expo/cliresolveRealEntryFilePath对相对路径原样返回,没有按项目根解析成绝对路径。

macOS 上不触发(gradle 传绝对路径),所以上游在 macOS 构建正常、Windows 用户无法本地出包。

上游反馈

  • 已向 expo 提交 issue(expo/expo#49659,附最小复现仓库 expo-bug
  • 被关闭。expo 确认这是已知问题,已在 expo/expo#44414(SDK 55)修复,但属于破坏性变更,不 backport 到 SDK 54。因此 SDK 54 需要自行补丁。

修复

移植 expo/expo#44414 的核心改动:resolveRealEntryFilePath 对相对路径先基于 projectRoot 解析为绝对路径,再走原有 realpath 逻辑:

if (!path.isAbsolute(entryFile)) {
  entryFile = path.resolve(process.cwd(), projectRoot, entryFile);
}

通过 pnpm patchpatches/@expo__cli@54.0.23.patch)应用,pnpm install 自动重新应用,可持续维护。升级 SDK 55+ 后可移除。

验证

  • expo export:embed 相对 entry-file:Bundled 成功(修复前 Unable to resolve ./index.js from <repo-root>
  • gradle assembleRelease:BUILD SUCCESSFUL,产出签名 APK
  • 模拟器安装实测正常
  • 相对与绝对 --entry-file 均能打包

备注

  • 仅针对 expo SDK 54(@expo/cli 54.0.23);SDK 55 已内置修复,无需此补丁
  • SDK 52+ 的 monorepo 由 expo 自动处理;metro.config.js 中手动 watchFolders/nodeModulesPaths 属废弃写法(expo 官方建议清理),与本 PR 独立

…t 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 <repo-root>/'.

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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant