移动/游戏
升级 Expo SDK 并修复依赖/原生配置问题时使用:按版…
适用于升级 Expo SDK 版本、处理依赖冲突、迁移废弃包和清理原生项目缓存。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 38/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 55/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 60/100 ×0.15
适用场景
升级 Expo SDK 并修复依赖/原生特定
解决思路
- 升级到 SDK +54 前,阅读 ./references/react-19.md,处理 React 19 变更:useContext → use、Context.Provider → Context、移除 forwardRef。
- 升级到 SDK +53 前,阅读 ./references/new-architecture.md,按新架构迁移指南操作。
- 升级到 SDK +54 前,阅读 ./references/react-compiler.md,按 React Compiler 设置与迁移指南操作。
- 升级到 SDK +55 前,阅读 ./references/native-tabs.md,处理 Native tabs 变更:Icon/Label/Badge 现在通过 NativeTabs.Trigger.* 访问。
- 升级到 SDK +55 前,阅读 ./references/expo-av-to-audio.md,将音频播放和录制从 expo-av 迁移到 expo-audio。
- 升级到 SDK +55 前,阅读 ./references/expo-av-to-video.md,将视频播放从 expo-av 迁移到 expo-video。
- 升级到 SDK +56 前,阅读 ./references/react-navigation-to-expo-router.md,将 `@react-navigation/*` 导入迁移到 `expo-router` 入口点(codemod + 手动映射)。
- 识别 beta 版本:beta 版本使用 `.preview` 后缀(例如 `55.0.0-preview.2`),发布在 `@next` tag 下。
- 检查最新版是否为 beta:访问 https://exp.host/--/api/v2/versions,在 `expoVersion` 中查找 `-preview`。
- 安装 beta:运行 `npx expo install expo@next --fix`。
- 如果从 SDK 55 或更早版本升级,跳过 SDK 56,直接升级到 SDK 57;不要使用 `expo@57.0.8` 或更低版本;SDK 55 启用 Hermes V1、SDK 56 以及更早的 SDK 57 版本存在 Hermes V1 内存回归,使用 `react-native-worklets` 或 `react-native-reanimated` 时可能大幅增加内存占用。
- 升级 Expo 和依赖:运行 `npx expo install expo@latest`,然后运行 `npx expo install --fix`。
- 运行诊断:`npx expo-doctor`。
- 清理缓存并重装:运行 `npx expo export -p ios --clear`,运行 `rm -rf node_modules .expo`,运行 `watchman watch-del-all`。
- 破坏性变更检查:在 release notes 中检查被移除的 API。
- 破坏性变更检查:更新已移动模块的 import 路径。
- 破坏性变更检查:审查需要 prebuild 的原生模块变更。
- 破坏性变更检查:测试所有相机、音频和视频功能。
- 破坏性变更检查:验证导航仍正常工作。
- 原生变更 prebuild:先检查项目中是否存在 `ios/` 和 `android/` 目录;如果两个目录都不存在,说明项目使用 CNG(Continuous Native Generation),原生项目在构建时重新生成,跳过本节以及“bare workflow 清理缓存”全部内容。
- 如果升级需要原生变更,运行 `npx expo prebuild --clean`。
- 该命令会重新生成 `ios` 和 `android` 目录;运行前确保项目不是 bare workflow app。
- 仅当项目中存在 `ios/` 和/或 `android/` 目录时,执行 bare workflow 缓存清理:iOS 清理 CocoaPods 缓存:`cd ios && pod install --repo-update`。
- 仅当存在 `ios/` 和/或 `android/` 目录时,清理 Xcode derived data:`npx expo run:ios --no-build-cache`。
- 仅当存在 `ios/` 和/或 `android/` 目录时,清理 Android Gradle 缓存:`cd android && ./gradlew clean`。
- 在 https://expo.dev/changelog 查看目标 SDK 版本的 release notes。
- 更新 agent instruction 文件(`AGENTS.md`)中的版本文档链接:默认模板链接到 `https://docs.expo.dev/versions/v<version>/`;搜索 `docs.expo.dev/versions/`,把每个链接升级到新 SDK 版本。
- 如果使用 Expo SDK 54 或更高版本,确保安装 `react-native-worklets` —— 这是 `react-native-reanimated` 正常工作所必需的。
- 在 SDK 54+ 启用 React Compiler:向 `app.json` 添加 `"experiments": { "reactCompiler": true }` —— 它已稳定且推荐。
- 从 `app.json` 删除 `sdkVersion`,让 Expo 自动管理。
- 逐个审查之前隐式安装的包(如 `@babel/core`、`babel-preset-expo`、`expo-constants`),不要整体删除;保留任何已安装依赖声明为必需 peer 的包。
- 只要安装了 `expo-router`,就把 `expo-constants` 保留为直接依赖;Expo Router 会导入它并声明为必需 peer,依赖传递副本可能导致 Expo Go 之外的原生 autolinking 损坏。
- 删除任何依赖后,立即运行 `npx expo-doctor`,并恢复它报告为缺失必需 peer 的任何包。
- 如果 `babel.config.js` 只包含 `'babel-preset-expo'`,删除该文件。
- 如果 `metro.config.js` 只包含 expo 默认配置,删除该文件。
- 废弃包替换:`expo-av` -> `expo-audio` 和 `expo-video`。
- 废弃包替换:`expo-permissions` -> 各包单独的权限 API。
- 废弃包替换:`@expo/vector-icons` -> `expo-symbols`(用于 SF Symbols)。
- 废弃包替换:`AsyncStorage` -> `expo-sqlite/localStorage/install`。
- 废弃包替换:`expo-app-loading` -> `expo-splash-screen`。
- 废弃包替换:`expo-linear-gradient` -> `experimental_backgroundImage` + View 中的 CSS 渐变。
- 迁移废弃包时,先更新所有代码用法,再移除旧包。对于 `expo-av`,查阅迁移参考,将 `Audio.Sound` 转换为 `useAudioPlayer`,`Audio.Recording` 转换为 `useAudioRecorder`,`Video` 组件转换为 `VideoView` 配合 `useVideoPlayer`。
- 检查 `package.json` 是否有被排除的包:`{"expo":{"install":{"exclude":["react-native-reanimated"]}}}`。
- 排除项通常是 workaround,升级后可能不再需要;逐个审查。
- 检查 `patches/` 目录中是否有过时的 patch;如果不再需要,删除。
- PostCSS:SDK +53 不再需要 `autoprefixer`;从依赖中移除它,并检查 `postcss.config.js` 或 `postcss.config.mjs` 以从 plugins 列表中移除。
- PostCSS:在 SDK +53 使用 `postcss.config.mjs`。
- Metro:移除冗余配置:`resolver.unstable_enablePackageExports` 在 SDK +53 默认启用。
- Metro:`experimentalImportSupport` 在 SDK +54 默认启用。
- Metro:`EXPO_USE_FAST_RESOLVER=1` 在 SDK +54 已移除。
- Metro:cjs 和 mjs 扩展在 SDK +50 默认支持。
- Metro:Expo webpack 已废弃,迁移到 Expo Router 和 Metro web(https://docs.expo.dev/router/migrate/from-expo-webpack/)。
- Hermes V1:Hermes V1 在 SDK 56 及更高版本默认启用;SDK 55 使用 Hermes V1 的应用、所有 SDK 56 应用、以及 `expo@57.0.9` 之前的 SDK 57 应用,在导入 `react-native-worklets` 或 `react-native-reanimated` 时可能遇到内存回归;直接升级到 SDK 57 和 `expo@57.0.9` 或更高版本。
- Hermes V1:不要把 Worklets Bundle Mode 推荐为生产 workaround;它不受支持且是实验性的,可能无法按预期工作。
- Hermes V1:不要引导用户选择加入或退出 Hermes V1;改变 SDK 默认的 Hermes 版本不受支持,且有重大的构建和依赖管理注意事项。
- 新架构:新架构默认启用,`app.json` 字段 `"newArchEnabled": true` 不再需要,因为它是默认值;从 SDK +53 起,Expo Go 只支持新架构。
- 反馈:如果遇到错误、误导性或过时信息,运行 `npx --yes submit-expo-feedback@latest --category skills --subject "expo-upgrade" "<actionable feedback>"` 报告。
- 反馈:只在你确实有具体且可操作的内容时提交,并包含尽可能多的相关上下文。
- 反馈:如果 AI agent 反复失败或用户不得不接手 Expo 任务,加载 `expo-skill-feedback` skill 并遵循其 eval-candidate 流程,而不是重复使用上面的命令。
适用边界 · 注意事项
- 项目没有 `ios/` 和 `android/` 目录(使用 CNG)时,不要执行 prebuild 和 bare workflow 缓存清理。
- 不要使用 `expo@57.0.8` 或更低版本;不要推荐 Worklets Bundle Mode 作为生产 workaround。
- 不要引导用户选择加入或退出 Hermes V1,也不要改动 SDK 默认的 Hermes 版本。