记录一次把 expo-doctor 修到 17/17:Clerk + Expo SDK 54 下的 peer 依赖缺失与 native module 重复版本
这篇文章记录一次真实踩坑:expo-doctor 从 15/17(2 项失败) 一路修到 17/17 全绿,并把“以后怎么跑”固化成一个脚本,避免每次临时设置环境变量。
适用范围(先对号入座)
Expo SDK:54
使用:
@clerk/clerk-expo包管理器:Bun(但思路对 npm/yarn/pnpm 也一样)
现象关键词:
Missing peer dependency/duplicate native module dependencies/expo install --check显示正常但expo-doctor仍失败
TL;DR(结论先行)
缺少 peer dependency:按提示把
expo-auth-session作为应用的直接依赖安装(用expo install对齐 SDK 版本)。native 模块重复版本:根因通常也是上面这件事(peer 没装在顶层导致依赖树里出现第二份
expo-*)。expo install --check绿但expo-doctor红:expo-doctor里还有expo-router的额外检查,它会对package.json的版本范围字符串做严格对比。防复发:加一个
doctor脚本,统一入口运行。
1. 现象:为什么会报这两类错误?
运行:
bunx expo-doctor当时出现两类问题:
缺少 peer 依赖(以 Clerk 为例)
Missing peer dependency: expo-auth-sessionRequired by: @clerk/clerk-expo
duplicate native modules
expo-application / expo-constants / expo-crypto / expo-linking / expo-web-browser出现两份一份在顶层
node_modules/expo-*另一份藏在
node_modules/expo-auth-session/node_modules/expo-*
报错输出(摘录)
这段我建议保留在博客里:后续回看能立刻对上当时发生了什么。
15/17 checks passed. 2 checks failed. Possible issues detected:
✖ Check that required peer dependencies are installed
Missing peer dependency: expo-auth-session
Required by: @clerk/clerk-expo
Advice:
Install missing required peer dependency with "npx expo install expo-auth-session"
✖ Check that no duplicate dependencies are installed
Found duplicates for expo-application:
├─ expo-application@7.0.8 (at: node_modules\expo-application)
└─ expo-application@6.1.5 (at: node_modules\expo-auth-session\node_modules\expo-application)
...2. 为什么“重装 node_modules”也不一定能解决?
很多人第一反应是删掉 node_modules 再装一遍,但这类问题往往会“原样复现”。原因很简单:
重装只能清理安装产物
依赖解析结果是由
package.json的版本约束 + lockfile 决定的
当 expo-auth-session 没被应用显式安装、或安装方式不对齐 Expo SDK 时,它可能以“传递依赖”的形式出现,并携带一套自己的 expo-* 依赖版本。由于这些属于 native module,同一个原生构建里只能容纳一份版本,于是 expo-doctor 会要求你去重。
结论:要彻底解决重复版本,关键是让 expo-auth-session 成为应用的直接依赖,并由 Expo 帮你选择 SDK 兼容版本。
3. 修复过程(一步一步复现/验证)
Step 1:按 Expo SDK 对齐安装 expo-auth-session
在 client 目录执行:
bunx expo install expo-auth-session预期变化:
peer dependency 的错误消失
expo-auth-session相关的expo-*duplicate 也会跟着消失(依赖树被对齐后可 hoist/去重)
当时状态从 15/17 变为 16/17。
Step 2:处理“expo install --check 没问题,但 expo-doctor 仍失败”
这里是最容易困惑的一段:
你可能看到:
expo install --check
Dependencies are up to date但 expo-doctor 仍报:
✖ Check that packages match versions required by installed Expo SDK原因:expo-doctor 不止做“Expo SDK bundled native modules”的版本校验,它还会跑 expo-router 的额外 doctor 检查。
这类检查有一个非常坑的点:它不仅看你“装了哪个版本”,还会看你 package.json 里写的版本范围字符串。
例如某次直接给出了:
🔧 Patch version mismatches
package expected found
@react-navigation/bottom-tabs ^7.4.0 ^7.4.8注意:^7.4.8 从语义上是 ^7.4.0 的子集(更严格、只允许 7.4.8 以上的 7.x),但 doctor 这里做的是“字符串/规则匹配”,因此仍可能判定为不符合期望。
处理方式:
让
@react-navigation/*满足expo-router的期望范围同时把
package.json的范围写回 doctor 期望的^7.4.0
Step 3:把运行方式固化成脚本(避免手动设置环境变量)
为了避免某些环境下 Node warning 输出影响 doctor 的稳定性,我们把运行入口固化为:
"doctor": "cross-env NODE_NO_WARNINGS=1 bunx expo-doctor"以后只需:
bun run doctor4. 最终结果
bun run doctor:17/17 checks passed. No issues detected!
5. 本次改动点(可审计)
client/package.json新增:
expo-auth-session(满足@clerk/clerk-expopeer 依赖,并对齐 Expo SDK)调整:
@react-navigation/bottom-tabs版本范围回到^7.4.0(满足 doctor 期望)新增脚本:
doctor新增 devDependency:
cross-env
6. 防复发 checklist
需要 Expo 原生模块时,优先使用
expo install <pkg>,不要随手bun add/npm i。expo-doctor标红时,先区分:Expo SDK 依赖校验问题(
expo install --check往往能提示)其他工具链/框架的额外 doctor 校验(例如
expo-router)
给团队统一入口:
bun run doctor(避免每个人手动设环境变量、复制命令)。
注:文章使用GPT总结