资讯动态

Nx 多仓库批量迁移实战指南:用 nx migrate 编排器与 Agent 一次性升级多个仓库

发布时间:2026/9/10 13:32:26 来源:尧图企业网站定制
Nx 多仓库批量迁移实战指南用 nx migrate 编排器与 Agent 一次性升级多个仓库【免费下载链接】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/nxnx migrate是 Nx 官方提供的一键迁移命令而本仓库中 Nx 23 起引入的“编排式迁移”orchestrated migrate机制则把单仓库的一次性迁移升级为可持续、可恢复、可交给 AI Agent 逐条执行的耐久流程。本文围绕.claude/skills/nx-multi-repo-migrate/SKILL.md中沉淀的批量迁移方法论结合本仓库packages/nx/src/command-line/migrate/下 Orchestrator、Worker、Run-State、Handoff 等源码实现完整讲解如何把多个仓库如nx、ocean、nx-labs、nx-examples、nx-console协调迁移到同一个目标版本并逐仓推送分支、打开相互关联的草稿 PR。读完你将掌握编排器模式的完整命令链、AI 迁移提示prompt的处理协议、崩溃恢复与 step-action 决策矩阵以及包管理器差异、版本门控、基线漂移等实战陷阱的应对方法。为什么要“编排”而不是一把梭传统做法是对每个仓库依次执行nx migrate VERSION再手动跑迁移这在多仓库场景下有三个痛点迁移可能改写源码。跨越多个 beta 版本如beta.23 → beta.25会拉取其间所有版本的迁移真实改动代码例如CreateNodesContextV2 → CreateNodesContext重命名。逐仓手工确认极易遗漏。迁移失败没有恢复点。一次--run-migrations跑一半崩溃只能从头再来且无法区分“已经应用过的迁移”与“还没跑的迁移”。AI 提示prompt-only migration无人认领。部分迁移只输出一段给人类/Agent 的说明文字需要有人真正读它并落地修改传统流程里常常被忽略。Nx 23.2.0-beta.8 起的编排式迁移把nx migrate --run-migrations变成一台“自动配药机”它一次只向外部 Agent 发放一个步骤dispenseAgent 原样执行该步骤给出的命令再运行next对账reconcile如此循环直到出现actioncomplete的结束块。整个流程没有常驻进程运行状态全部落盘在.nx/migrate-runs/run-id/下因此随时可以中断、恢复、续跑。注本文描述的编排器能力以当前仓库 packages/nx 中nx migrate的实现为准SKILL.md 中提到的“目标版本示例23.0.0-beta.25”与门槛版本23.2.0-beta.8属于当时的运行实例实际使用时以你安装的 Nx 版本是否支持NX_MIGRATE_ORCHESTRATOR环境变量为准。第一步确认目标版本与仓库清单验证目标版本真实存在发布 24 小时内的新版本可能被本机 registry 的“发布时长门控”过滤掉所以先显式确认npm view nxVERSION version如果输出为空或回落到低版本说明目标版本在当前的 npm registry 视图中不可见按后文“版本门控”一节的绕过方式处理。明确仓库清单显式给出仓库列表或直接采用 Polygraph 会话里已有的仓库或不提供时使用默认集合nx、ocean、nx-labs、nx-examples、nx-console均属nrwl组织。用 Polygraph 技能建会话通过polygraphskill 发现仓库、选择组织并创建/加入会话。它负责鉴权与会话生命周期不需要在这里重新实现。之后每个仓库的工作都交给独立的子 Agentspawn_agent并行执行父进程只负责轮询show_agent与收尾推送。第二步每个仓库的迁移指令子 Agent 协议SKILL.md 为每个子 Agent 定义了 11 步指令下面逐条结合源码展开。1. 从远端基线的干净分支出发不要从克隆自带的检出分支开始先 fetch 再基于origin/base建分支避免继承陈旧的克隆或工作目录里的临时分支git fetch origin base git checkout -B migrate-nx-VERSION origin/base2. 根据锁文件识别包管理器锁文件包管理器package-lock.jsonnpmyarn.lockYarn Berrypnpm-lock.yamlpnpmbun.lock/bun.lockbbun3. 先安装让node_modules停留在迁移前版本这是最容易翻车的一步。nx migrate读取的是node_modules里的“from”版本而不是package.json——如果node_modules已经停在目标版本它会找到0 个迁移并静默跳过。执行前务必确认node -p require(./node_modules/nx/package.json).version4. 生成迁移计划npmx nx migrate VERSION这会更新package.json并生成migrations.json。从源码看编排模式下初始化还会把完整的migrations.json原样快照为plan-0.json存入 run 目录见 orchestrator.ts后续 Worker 每次执行都从快照读取计划而不是依赖工作区里那个随时可能被删的migrations.json。5. 二次安装必须是“可变”安装迁移生成器可能改动依赖所以再装一次。严禁设置CItrue——它会让 Yarn Berry 进入不可变安装、pnpm 进入 frozen 模式安装和迁移会静默失败。按包管理器分别处理包管理器可变安装命令npmnpm installYarn Berryyarn install带YARN_ENABLE_IMMUTABLE_INSTALLSfalsebunbun installpnpmpnpm install --no-frozen-lockfile --config.confirm-modules-purgefalse6. 先提交版本升级与迁移改动隔离在跑任何迁移之前把版本升级单独提交避免迁移提交把package.json的版本改动一起吞进去git add package.json lockfile # 不要 add migrations.json git commit -m chore(repo): migrate to nx VERSION不要在提交信息里提 AI/Claude。这一步对应源码中commitCheckpointBeforeMigrations的“checkpoint 提交”思想——先落盘现有工作树状态保证第一个迁移提交不会吸收无关改动见 migrate-commits.ts。7. 编排循环目标版本 ≥ 23.2.0-beta.8 时先清理工作区git status --porcelain删除任何未跟踪的“Agent 垃圾文件”子 Agent 把仓库目录当$HOME用时产生的.bashrc/.zshrc/.claude/*等——循环的 checkpoint 提交会执行git add -A这些文件会被扫进提交里。然后启动循环NX_MIGRATE_ORCHESTRATORtrue pm nx migrate --run-migrations --create-commits --commit-prefixchore(repo): [nx migration] 要点--create-commits是必须的自定义--commit-prefix在没有它时会直接报错。源码里resolveCreateCommits强制编排模式走 agentic 默认值migrate-commits.ts。第 5 步的可变安装环境变量要保留到这条及之后每一条循环命令上因为循环自己会触发安装。执行前先确认.nx/migrate-runs已被.gitignore覆盖编排器在每次 init/reconcile 前都会探测该目录的“提交暴露度”未忽略unignored或已被跟踪tracked都会拒绝继续防止git add -A把运行状态扫进提交orchestrator.ts。仓库为此专门提供了23-0-0-add-migrate-runs-to-git-ignore迁移见 types.ts。循环会打印nx_migrate_step块每个块携带commandnx migrate --run-migrationid --run-idid原样执行nextnx migrate --run-idid执行它来记录结果并拿到下一步。重复直到出现actioncomplete的块。提交由 Nx 逐个迁移自动创建该模式下默认开启不要再手工提交提交信息通过 stdin 传给 git因此经典模式里--commit-prefix中(导致的 shell 崩溃在这里不适用。提示型AI迁移当某一步是 prompt 迁移时Worker 会打印nx_migrate_prompt块。你要亲自在仓库里应用该提示规则与经典模式的第 8 步相同然后在next指明的路径写入 handoff 文件{ status: success, summary: 你做了什么 }无法应用时写{ status: failed, summary: 原因 }提示不适用时写{ status: success, summary: 说明, outcome: skipped }。handoff 文件位于 run 目录的handoffs/子树下package/name.json这是 Agent 唯一被预授权的写入范围types.ts。对账时 Orchestrator 的foldHandoffs会读取并校验该文件status必须是success或failedsummary必须是字符串多余字段归入extrashandoff.ts。成功后 Orchestrator 会替该步骤提交并把结果分类进 commit ledger失败/跳过则记录“commit debt”等待后续提交吸收。失败 / 死亡的步骤对账命令会列出合法的--step-action选项见 step-actions.tsaction含义使用时机retry重新执行该步骤失败但工作树里没有残留改动retry-clean先git reset --hard回滚再重试优先选用前提是工作树可验证干净skip跳过该步骤仅当步骤确实不适用adopt采纳已死亡 Worker 实际落地的改动died 的 Worker 改动真实生效时注意retry-clean有严格的安全门工作树必须可验证干净否则 Orchestrator 直接拒绝orchestrator.ts。崩溃 / 超时恢复运行状态全部在.nx/migrate-runs/run-id/run.jsonrun-state.ts带格式版本号与字段级校验。用相同的环境变量重跑nx migrate --run-migrations会恢复同一 run 而不是重新开始——不要在子 Agent 被杀后重新迁移。恢复时会打印进度已应用/已跳过/剩余/等待决策并使用--step-action解决挂起的失败步骤orchestrator.ts。编排循环不可用时的回退如果目标版本早于 23.2.0-beta.8或 Agent 检测门CLAUDECODE环境变量未触发导致走了经典循环则按第 8 步回退。8. 经典回退流程不要用--create-commits经典模式里 Nx 会把--commit-prefixchore(repo): [nx migration] 原样未经转义地交给/bin/sh执行(会让 shell 崩溃Syntax error: ( unexpected迁移被静默丢弃。正确做法只跑一次nx migrate --run-migrations应用整个列表不要只跑子集手工为每个迁移提交例如git commit -m chore(repo): [nx migration] namegit commit -m能正常处理括号AI 迁移必须由你亲自应用——--run-migrations只跑确定性的 codemod重点是remove-removed-typescript-eslint-extension-rules它会删除 typescript-eslint v8 已移除的规则如typescript-eslint/no-extra-semiflat config 里残留一条这类规则会直接让 ESLint loader 崩溃→ nx 报 “Failed to process project graph” → CI 变红同时把 prompt-only 迁移写进tools/ai-migrations/**/*.md并打印“Next steps for the AI agent driving this run: apply the deferred prompts.”——这行字就是写给你子 Agent的读每个提示并落地修改不要留给人类。遵守每个提示的 “passing baseline”保持 lint/typecheck 通过绝不关掉用户显式配置的规则对于新“预置”启用的规则用一句短注释关闭它而不是改源码去迁就它。源码佐证Nx 在检测到自身正运行在另一个 Agent 内部时会通过isInsideAgent()底层isAiAgent()嗅探父进程环境变量覆盖 Claude Code、Cursor、OpenCode、Codex、Gemini、Replit 等见 inception.ts自动跳过其“嵌套 agentic 流程”把提示迁移交给外层 Agent——这正是 SKILL.md 说的“nx 自动跳过嵌套 Agent 流程是评审跳过绝不是跳过迁移的许可”。9. 宣布完成前的验证nx run-many -t lint --skip-nx-cache必须能解析项目图并全部通过被移除的规则崩溃只在解析项目图时才暴露并尽可能对受影响项目做 typecheck/build。修复迁移引入的破坏对真正的框架大版本不兼容Angular/React/TS 主版本升级要交给人类而不是绕过去。10. 收尾清理删除tools/ai-migrations/仅经典模式会创建它编排循环不产生该目录删除migrations.json保留.nx/migrate-runs/gitignored 的临时目录留作事后复盘若迁移改了依赖重新安装并提交锁文件更新。11. 汇报汇报内容旧版→新版、升级的包、运行模式编排 vs 经典、跑的确定性迁移 提交、每个 AI 提示及你如何应用或按 handoff 说明为何 N/A、用过的--step-action决策、最终 lint/typecheck/build 状态、未解决的失败类型/名称冲突、框架大版本破坏。真正的阻塞项留给人类不要发明绕过方案。处理“部分完成 / 已在目标版本”的仓库如果node_modules已在目标版本nx migrate VERSION会找到 0 个迁移。要重新应用之前被跳过的迁移——确定性的remove-removed-*codemod 或 AI 提示——用显式--from重新生成完整列表nx migrate VERSION --fromnx原版本迁移会检测已应用状态并自动 no-op因此只会安全地重跑缺失的部分然后按第 7–11 步收尾。迁移会改写源码提交前审查跨多个 beta 的跳跃如 beta.23→beta.25会拉取每个中间版本的迁移可能真实重写代码如CreateNodesContextV2 → CreateNodesContext。子 Agent 提交前应审查非依赖 diff。已在当前版本的仓库做单 beta 跳跃时通常合理地没有迁移。源码佐证Worker 会记录步骤的gitRefBefore、fileChanges、gitRefAfter等 outcome 字段run-state.ts提交后生成的 commit ledger 条目与stepsToPendingMigrations一起写进提交正文方便git log -p追溯哪些迁移的 diff 被吸收进哪个提交migrate-commits.ts。第三步逐仓推送 打开 PR不要等最慢的仓库不要在“最慢的仓库”上设置屏障。子 Agent 一报成功立即对该仓库单独push_branch分支名migrate-nx-VERSION并create_pr——这样它的 CI 立刻开始一个卡在沙箱里的慢仓库不会拖累其他仓库for each repo, as its child reaches terminal success (not in a barrier): push_branch(repo) → create_pr([repo])PR 之所以保持“相互关联”是因为它们加入同一个 Polygraph 会话——关联关系在会话不在一次批处理调用。提交信息 scope 用repo能通过 nx 的 commitlint。全部打开后打印 Polygraph 会话 URL。验证一次单次批处理create_pr会在创建时给每个 PR 正文写入兄弟 PR 的交叉引用增量创建时确认 Polygraph 会回填早先 PR 正文里指向后开 PR 的链接而不是每个 PR 只链会话。若不会回填又需要正文内交叉链接就回退到所有子 Agent 完成后的单次批处理create_pr。开 PR 前的逐仓核验清单package.json中nx与nx/*精确落在目标版本未被发布时间门控静默降级到latest迁移确实跑过不是因node_modules已在目标版本而跳过包括确定性的remove-removed-*codemodAI 迁移提示由子 Agent 应用过不只是写出编排模式每个提示步骤都有 success handoff经典模式tools/ai-migrations/应用后删除。两种情况都删除了migrations.jsonnx run-many -t lint --skip-nx-cache能解析项目图并全部通过可行时检查 typecheck/build版本升级提交chore(repo): migrate to nx VERSION 每个应用过的迁移/提示一个chore(repo): [nx migration] …提交都在migrate-nx-VERSION分支上编排模式由 nx 自动提交经典模式手工提交——二者只取其一编排运行以complete块结束——没有遗留failed/died/awaiting-prompt-outcome的步骤也没有未解决的 commit-debt / 安装失败告警子 Agent 报告与仓库实际状态核对git log、git status、git show --stat——委派可能谎报已执行checkpoint 提交也可能扫入垃圾当某次 checkpoint 提交只包含垃圾且该轮迁移未改动任何文件时可安全丢弃git reset --hard回到它之前那个提交碰撞 / 编译 / 框架大版本错误已在子 Agent 报告中上抛给人类解决实战陷阱真实 5 仓库运行中踩过的坑新鲜 beta/canary 被发布时间门控隐藏 → 静默降级到 latest发布不足 24 小时的目标会被供应链发布时间门控过滤在 nx-dev 机器上可能有多达三处~/.npmrc的min-release-age1npm/bun、~/.config/pnpm/rc的minimum-release-age1440pnpm、以及指向本地 age-gating 代理http://localhost:7190常处于宕机状态 →ECONNREFUSED的~/.yarnrc.ymlregistry。目标被过滤时nx migrate不会报错——它静默地把整个nx/*组解析到最新可见版本如latest23.0.1 而不是 23.1.0-beta.5于是仓库“迁移”到了错误版本。按命令绕过不要改全局配置# npm / pnpm / bun npm_config_min_release_age0 npm_config_minimum_release_age0 pm nx migrate ... # Yarn Berry 额外需要 YARN_NPM_REGISTRY_SERVERhttps://registry.npmjs.org/ YARN_NPM_MINIMAL_AGE_GATE0 pm nx migrate ...pnpm 的 nx-migrate 临时目录pnpm add还需要PNPM_CONFIG_STRICT_DEP_BUILDSfalse否则ERR_PNPM_IGNORED_BUILDS中止。注意pnpm 忽略 npm 风格的min-release-age只认自己的minimum-release-age——这就是为什么 pnpm 仓库可能正确解析 beta而 yarn/npm 兄弟仓库却静默降级。务必逐一核对每个仓库落在精确目标版本而非 latest。pnpm 在 Bash 沙箱下会死bun/yarn 不会截至 Claude Code 2.1.172Bash 工具默认沙箱化。pnpm 的内容寻址存储 clonefile()reflink node_modulespurge 会触发 macOS 规则com.apple.provenancexattr 移除、在虚拟 store 里创建.vscode/.idea目录等以及出站 TLS 问题导致install报ERR_PNPM_EPERM/ reflink /Operation not permittedbun 和 yarn 则能干净安装。Polygraph 子 Agent 有自己的沙箱~/.polygraph/config.json→agentOptions.claude.sandbox与~/.claude/settings.json→sandbox.enabled相互独立任一改动都只对重启后的新进程生效。pnpm 子 Agent 卡在沙箱/EPERM 错误时不要让它发明绕过方案剥 xattr、TLS shim、重定向 store而是禁用沙箱并重启或在未沙箱化的父进程里迁移该仓库发起仓库就地迁移克隆位于~/.polygraph/sessions/id/repos/org/repo在那里关闭沙箱跑同样的 install→migrate→install 步骤再推送。基线在运行中移动第 1 步从origin/base建分支只处理初始状态默认分支仍可能在运行中途前进——例如另一个版本升级 PR 在你下方合入实际发生过ocean 的main在一个已开 migrate PR 下方从 beta.23 跳到 beta.25把它变成冲突。用落后计数检测git rev-list --count migrate-nx-V..origin/base并留意已开的升级 PR。基线移动时把分支重做到新基线上——只需重做基线实际前进的仓库。重做到更新基线还可能缩小 diffbeta.25→rc.0 的重做只改依赖而旧 beta.23→rc.0 跑了 16 个迁移并重写了源码。发起仓库就地运行发起仓库就在你的工作目录里运行迁移它会切换分支并搅动node_modules。事后恢复它——或者在真实基线的一次性 worktree里跑迁移git worktree add -B migrate-nx-V /tmp/wt origin/base这样工作副本永不被触碰。但 worktree 里全新完整安装会复制巨大node_modules可能ERR_PNPM_ENOSPC在其它克隆的安装之上叠加 inode/磁盘压力。规避在主检出里跑nx migrate规划步骤复用已装的node_modules这样 migrate 能升级整个nx/*组——没有node_modules它只升级nx本身把package.jsonmigrations.json复制到 worktree 分支恢复主检出当没有迁移要跑时在 worktree 里只做pnpm install --lockfile-only而非完整安装。推送后git worktree remove清理分支 ref 保留。一个具体的源码碰撞CreateNodesContextV2 → CreateNodesContext重命名迁移与本地 vendored 的interface CreateNodesContext extends CreateNodesContextV2冲突产生自引用的extends CreateNodesContextTS2310。上抛给人类最小修复是给导入起别名import { CreateNodesContext as NxCreateNodesContext } from nx/devkit。该重写是beta.24的迁移——从 beta.25 起步会完全跳过它。推送 / 鉴权陷阱SSH agent 可能中途掉线communication with agent failed——SSHgit push随之失败重试或让用户重新ssh-add。只读的GH_TOKEN环境变量可能遮蔽带写权限的 keychain 登录每次写操作push、pr edit、pr merge --auto都返回Resource not accessible by personal access token。给 gh 写操作加env -u GH_TOKEN前缀以回退到 keychain 鉴权。Polygraphpush_branch内部会做pull --rebase所以它无法强制更新被 rebase 的分支——这类情况直接用git push --forceSSH/HTTPS。Polygraphcreate_pr在nrwl/nx 上偶发 401Bad credentials而同批的兄弟 nrwl 仓库却正常——只需重试失败的仓库通常第 2–3 次就成功。个人GH_TOKEN能push到 nrwl/nx但在某些其他 nrwl 仓库如 nrwl/nx-examples被403 拒绝且无法在 nrwl/nx 上创建 PR——所以对这类情况改用 Polygraphpush_branch/create_pr后端鉴权由于push_branch只能快进需要更新已推送分支时优先新增提交而非 amend。若create_pr持续失败nrwl/nx 的 PR 创建仍可能需要“已推送分支 预填 compare URL”的回退方案。关键源码索引想深入理解编排机制可按以下路径阅读当前仓库源码编排器入口与 dispense/对账循环run/orchestrator.ts单个迁移执行 Workerrecorded run 与 standalonerun/worker.tsrun 状态机与持久化run.json、格式版本、保留策略run/run-state.tscommit 决策、checkpoint、commit ledgermigrate-commits.ts--step-action合法值与运行时守卫step-actions.tshandoff 文件读写与校验agentic/handoff.ts.nx/migrate-runs路径与 agentic 类型定义agentic/types.tsAgent-in-Agent 检测agentic/inception.tsnx migrateCLI 参数定义--run-migration、--run-id、--create-commits、--commit-prefix、--from、--include等command-object.ts【免费下载链接】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),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价