
Nx 工作区中的 Expo SDK 56 迁移完整指南React 19.2、RN 0.85 与expo/metro实战【免费下载链接】nxThe Monorepo Platform that amplifies both developers and AI agents. Nx optimizes your builds, scales your CI, and fixes failed PRs automatically. Ship in half the time.项目地址: https://gitcode.com/GitHub_Trending/nx/nx本指南以nx/expo官方提供的 SDK 56 迁移说明ai-instructions-for-expo-56.md为主体骨架结合 packages/expo 中迁移生成器、版本常量与测试用例的源码实现系统讲解如何将包含 Expo 项目的 Nx 工作区从 SDK 53/54/55 迁移到 Expo SDK 56。读完你将掌握迁移前的项目盘点方法、Expo SDK 56 的精确目标版本矩阵、Metro/Babel/Jest 三大构建链的破坏性变更处理以及一套可复制的验证清单。说明本文所述版本号、命令与迁移逻辑均以当前仓库packages/expo的实现为准默认以 Expo SDK 56 为新项目默认 SDK见 versions.ts适用于集成式 Nx 工作区apps 下多项目、根package.json统一锁定版本与独立式工作区的常见场景。一、迁移前的准备工作盘点工作区中的 Expo 资产迁移的第一步不是改依赖而是完整盘点工作区中所有与 Expo 相关的项目与文件避免遗漏导致升级后出现一半项目能跑、一半项目报错的割裂状态。1.1 识别所有 Expo 项目在 Nx 工作区中Expo 应用通过starttarget 暴露给 Nx 任务系统因此可以用 Nx 的查询命令精确列出所有具备该 target 的项目nx show projects --with-target start这一步的作用是建立受影响项目清单后续所有迁移动作都应围绕这份清单展开。从源码层面看迁移脚本正是这样做的nx/expo在 SDK 56 迁移中通过 expo-apps.ts 的getExpoAppRoots函数遍历所有projectType application的项目并检查项目自身或工作区根目录的package.json中是否声明了expo依赖——新版本 Expo 应用在应用级package.json里用*占位、版本统一锁在根package.json因此该函数对项目级和根级package.json都会检查。1.2 定位所有 Expo 配置文件需要在工作区中搜索以下文件它们是迁移的主要修改对象app.json或app.config.{js,ts}——应用运行时配置metro.config.{js,ts}——Metro 打包器配置SDK 56 迁移的核心对象babel.config.{js,ts}——Babel 转译配置各项目project.json——检查是否有 Expo 相关的 targetstart、run-ios、run-android、export等。1.3 记录当前 SDK 版本对每个 Expo 应用读取其package.json或根package.json中expo字段记录当前所在的 SDK。最常见起点是 SDK 54 与 SDK 55若从 SDK 53 迁移还需额外处理jest.resolver.js的移除见第四章。1.4 检查 Detox E2E 项目如果工作区中包含 Detox 端到端测试需要提前识别在package.json依赖中搜索detox查找detox.config.js或.detoxrc.js文件。Detox 对 Expo SDK 的适配通常滞后于 SDK 发布因此这一步必须在迁移开始前完成详见第五章。二、Expo SDK 56 目标版本矩阵迁移时不要手动猜测各个包的版本直接对齐nx/expo在 versions.ts 中为 SDK 56 维护的版本常量包名目标版本说明expo~56.0.0SDK 主版本expo/cli~56.1.14CLI 工具链react^19.2.0React 运行时react-dom^19.2.0Web 端 React DOMtypes/react^19.2.0React 类型定义react-native0.85.3RN 核心精确锁定react-native-web~0.21.0Web 端渲染expo/metro~56.0.0SDK 55 起 Metro 的承载包expo/metro-runtime~56.0.14Metro 运行时babel-preset-expo~56.0.14Babel 预设jest-expo~56.0.4Jest 预设expo-splash-screen~56.0.10启动屏expo-status-bar~56.0.4状态栏expo-system-ui~56.0.5系统 UI 控制推荐做法在每个 Expo 项目目录内优先执行npx expo install --fix让 Expo 解析 SDK 56 精确兼容的原生模块版本随后再将版本回填/对齐到工作区根package.json。这与仓库中ensure-dependenciesensure-dependencies.ts的依赖声明策略一致根级锁定真实版本应用级保持*通配由根解析。三、迁移步骤按破坏性变更分类3.1 React 19.2 与 React Native 0.85Expo SDK 56 基于 React 19.2 与 React Native 0.85.3。操作清单将types/react更新到^19.2.0核查第三方库对 React 19.2 / RN 0.85 的兼容性重新执行全量类型检查nx run-many -t typecheck。3.2 Metro 改由expo/metro提供核心变更这是 SDK 56 迁移中影响面最大的一项。从 SDK 55 开始Expo 将 Metro 打包进expo/metro包族不再直接依赖独立的metro、metro-config、metro-resolver包。搜索模式查找metro.config.{js,ts}以及代码中对metro-config/metro-resolver的直接 import。操作清单将expo/metro~56.0.0添加为直接依赖。原因在于生成的metro.config.js与withNxMetro需要require(expo/metro/metro-config)而 pnpm 等严格依赖解析的包管理器不允许从传递依赖中 require——这正是仓库迁移脚本 replace-standalone-metro-for-expo-56.ts 在根与应用两级package.json中同时做删metro-config/metro-resolver、增expo/metro替换的原因根级用真实版本应用级用*Metro 配置改从 Expo 提供的实例取getDefaultConfig来自expo/metro-configmergeConfig来自expo/metro/metro-config移除对独立metro/metro-config/metro-resolver的直接依赖且不要直接安装expo/metro-config——expo-doctor 会将其标记为问题expo/metro已取代它若你的配置使用了nx/expo导出的withNxMetro包装保留不动它仍负责合并 Nx 工作区解析watchFolders、workspace 库等升级后清空 Metro 缓存npx expo start --clear。迁移前后metro.config.js的对照改写逻辑由 update-metro-config-for-expo-56.ts 实现且只改写生成器生成的形态自定义配置保持不动对应测试见 update-23-1-0.spec.ts// BEFOREExpo SDK 54 及更早的生成形态 const { withNxMetro } require(nx/expo); const { getDefaultConfig } require(expo/metro-config); const { mergeConfig } require(metro-config); const defaultConfig getDefaultConfig(__dirname); module.exports withNxMetro(mergeConfig(defaultConfig, {}), {});// AFTERExpo SDK 55/56 的生成形态 const { withNxMetro } require(nx/expo); const { getDefaultConfig } require(expo/metro-config); const { mergeConfig } require(expo/metro/metro-config); const defaultConfig getDefaultConfig(__dirname); module.exports withNxMetro(mergeConfig(defaultConfig, {}), {});如果对expo/metro的引入时机有疑问可参考 ensure-dependencies.ts它按expo版本的主版本号判断——SDK 55 时只安装expo/metroSDK 53/54 时仍保留独立expo/metro-config。3.3 Babel 预设升级SDK 56 将babel-preset-expo升级到~56.0.14。操作清单更新babel-preset-expo至~56.0.14移除已废弃的 Babel 插件旧的自定义 preset/plugin 需逐一核对是否仍被官方预设覆盖修改 Babel 后清空 Metro 缓存npx expo start --clear。3.4 Jest 配置与 winter runtimeExpo v54含 SDK 56依赖 winter runtime。nx/expo新生成的项目不再使用自定义jest.resolver.js改为在src/test-setup.ts中 mockexpo/src/winter/ImportMetaRegistry并 polyfillstructuredClone。操作清单若从 SDK 53 迁移删除jest.resolver.js及jest.config.ts中的resolver:配置项确保src/test-setup.ts包含ImportMetaRegistry的 mock 与structuredClonepolyfill更新jest-expo至~56.0.4。在 SDK 56 中winter runtime 还会惰性安装fetch、URL等全局对象而在 monorepo 中 Jest 会把这些惰性 getter 判定为测试代码作用域之外而报错。仓库迁移脚本 update-jest-winter-runtime-for-expo-56.ts 会在生成的 test-setup 中追加一段defineGlobal代码块用 runtime 自身的全局值直接覆盖这些惰性 getter使其在测试期间永不触发// src/test-setup.tsnx/expo SDK 56 迁移后的形态 jest.mock(expo/src/winter/ImportMetaRegistry, () ({ ImportMetaRegistry: { get url() { return null; }, }, })); if (typeof global.structuredClone undefined) { global.structuredClone (object) JSON.parse(JSON.stringify(object)); } // Expo SDK 55 winter-runtime 惰性全局的中和块 const defineGlobal (name, value) { try { Object.defineProperty(global, name, { value, configurable: true, writable: true, }); } catch { // 忽略不允许重定义这些全局变量的环境 } }; defineGlobal(fetch, globalThis.fetch); defineGlobal(Headers, globalThis.Headers); defineGlobal(Request, globalThis.Request); defineGlobal(Response, globalThis.Response); defineGlobal(FormData, globalThis.FormData); defineGlobal(URL, globalThis.URL); defineGlobal(URLSearchParams, globalThis.URLSearchParams);该脚本只处理同时满足包含ImportMetaRegistrymock、且尚无defineGlobal的生成文件因此是幂等的重复执行不会追加第二遍见 update-23-1-0.spec.ts 中的幂等性测试。3.5 Detox E2E 测试在迁移前先确认 Detox 是否已发布 Expo SDK 56 支持。若工作区包含 Detox 项目而 Detox 尚未支持 SDK 56必须先询问用户Your workspace contains Detox E2E tests. Confirm Detox supports Expo SDK 56 before proceeding, or these tests may not run after migrating.若 Detox 支持滞后可考虑将 E2E 方案迁移到 Maestro 作为替代仓库在 SDK 54 迁移文档 ai-instructions-for-expo-54.md 中同样给出了停留旧 SDK / 等待支持 / 换 Maestro三种备选路径。四、迁移后验证一套可复制的验收流程4.1 清空所有缓存npx expo start --clear rm -rf node_modules/.cache/metro-* nx reset4.2 按项目跑测试nx run-many -t test -p PROJECT_NAME4.3 跑全部受影响项目的测试与检查nx affected -t test,lint,typecheck4.4 真机/模拟器验证nx run PROJECT_NAME:run-ios nx run PROJECT_NAME:run-android4.5 对照迁移完成清单逐项勾选所有 Expo 应用锁定到 SDK 56 版本React 19.2 / React Native 0.85 兼容性已验证Metro 已通过expo/metro提供缓存已清空Babel 与 Jest 配置已更新所有测试通过应用可在 iOS 模拟器/真机运行应用可在 Android 模拟器/真机运行五、给执行迁移的 Agent/LLM 的执行纪律无论由人还是由 AI Agent 执行这套迁移都应遵循以下纪律这也是nx/expo官方迁移说明ai-instructions-for-expo-56.md中Notes for LLM Execution明确要求的行为准则系统性推进完整完成一个变更类别后再进入下一个类别每步都验证不要把所有修改一次性堆叠完再验证——每类变更后立即跑对应测试优先npx expo install --fix在每个项目内用它解析原生模块的兼容版本保持用户知情及时汇报进度并生成有意义的、分组的提交git commit使用 TodoWrite 工具跟踪进度将迁移清单拆成可勾选任务双平台验证Expo 变更常常对 iOS 与 Android 产生不同影响两者都要实测。六、常见问题速查症状原因处理方式Metro 打包报模块解析错误pnpm 下expo/metro仍是传递依赖将其提升为直接依赖根级锁版本、应用级*expo-doctor 提示expo/metro-config不应再直接安装独立expo/metro-config移除该依赖改用expo/metro与expo/metro-config子路径Jest 报 winter runtime 全局对象越界SDK 56 惰性全局与 Jest 作用域冲突在src/test-setup.ts追加defineGlobal中和块或直接跑 SDK 56 迁移脚本升级后启动报缓存相关错误Metro 缓存未清理npx expo start --clearrm -rf node_modules/.cache/metro-*Detox E2E 在升级后无法运行Detox 尚未支持 SDK 56先确认支持情况再迁移或评估 Maestro 等替代方案结语Expo SDK 56 迁移对 Nx 工作区的核心冲击点集中在三处React 19.2 / RN 0.85 的运行时升级、Metro 从独立包迁移到expo/metro包族、以及 Jest 对 winter runtime 的适配。这三处的迁移逻辑依赖替换、配置改写、test-setup 中和块在 packages/expo/src/migrations/update-23-1-0 中均有完整的生成器实现与 单元测试 佐证可作为大型工作区自动化迁移的参考范本。按分类推进、逐步验证、双平台实测的节奏执行即可将迁移风险控制在可接受范围内。【免费下载链接】nxThe Monorepo Platform that amplifies both developers and AI agents. Nx optimizes your builds, scales your CI, and fixes failed PRs automatically. Ship in half the time.项目地址: https://gitcode.com/GitHub_Trending/nx/nx创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考