切换机制)
Nx 20 迁移指南深入解析 useLegacyCache 与新一代数据库缓存DB Cache切换机制【免费下载链接】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 20 将本地任务缓存从基于文件目录的旧式缓存升级为基于数据库的缓存DB Cache但为了保证存量工作区平滑升级、避免缓存行为突变Nx 20.0.1 专门提供了一条迁移规则为未启用新缓存的工作区自动写入useLegacyCache: true。本文以这条迁移use-legacy-cache为线索结合仓库源码与测试用例讲解它的触发条件、变更前后的配置形态、底层缓存架构差异以及它与 Nx 21 的后续演进关系帮助你理解并掌控升级过程中的缓存配置。迁移背景Nx 20 为何需要useLegacyCacheNx 的本地缓存用于复用已执行任务的产物避免重复构建。在 Nx 19 及更早版本中缓存以文件目录的形式组织在本地旧式/legacy cache而 Nx 20 引入了以数据库为底层存储的新缓存实现DB Cache它在缓存读取、写入与清理的效率和能力上都有所不同。对于从旧版本升级上来的工作区Nx 不能擅自替用户切换缓存实现——不同实现的缓存键hash、产物格式与清理策略存在差异直接切换可能造成缓存失效甚至行为不一致。因此Nx 20.0.1 提供了专门的迁移规则SetuseLegacyCacheto true for migrating workspaces该规则在 packages/nx/migrations.json 中注册版本号为20.0.1并带有x-repair-skip: true标记表示该迁移不参与--repair修复流程use-legacy-cache: { version: 20.0.1, description: Set useLegacyCache to true for migrating workspaces, implementation: ./dist/src/migrations/update-20-0-1/use-legacy-cache, x-repair-skip: true, documentation: ./dist/src/migrations/update-20-0-1/use-legacy-cache.md }迁移逻辑源码级的完整执行流程迁移的核心实现在 packages/nx/src/migrations/update-20-0-1/use-legacy-cache.ts完整逻辑如下import { Tree } from ../../generators/tree; import { formatChangedFiles } from ../../generators/internal-utils/format-changed-files; import { readNxJson, updateNxJson } from ../../generators/utils/nx-json; import { NxJsonConfiguration } from ../../config/nx-json; export default async function update(tree: Tree) { const nxJson readNxJson(tree) as NxJsonConfiguration; if (!nxJson) { return; } // If workspaces had enableDbCache we can just delete the property // as the db cache is enabled by default in nx v20 if ((nxJson as any).enableDbCache) { delete (nxJson as any).enableDbCache; } else { (nxJson as NxJsonConfiguration { useLegacyCache: boolean }).useLegacyCache true; } updateNxJson(tree, nxJson); await formatChangedFiles(tree); }分支一已显式启用 DB CacheenableDbCache: true若工作区的nx.json中此前已手动配置过enableDbCache: true旧版本中该属性用于打开数据库缓存迁移会直接删除该属性。原因在源码注释中写得非常清楚If workspaces hadenableDbCachewe can just delete the property as the db cache is enabled by default in nx v20即在 Nx 20 中DB Cache默认开启enableDbCache已经失去意义删掉即可且不需要写入useLegacyCache——因为该工作区本就使用新缓存。分支二未显式启用 DB Cache默认情况对于绝大多数升级工作区未配置过enableDbCache迁移会写入useLegacyCache: true这表示该工作区在 Nx 20 中继续沿用旧式的文件目录缓存缓存行为与升级前保持一致。分支三nx.json不存在若迁移时读取不到nx.json函数直接返回不做任何修改if (!nxJson) return;。最后迁移通过updateNxJson(tree, nxJson)将修改写回配置文件并调用formatChangedFiles(tree)对变更后的文件做格式化保证生成的nx.json格式整洁。变更前后对比完整的 Sample Code Changes原文档给出了最典型的迁移前后差异。以targetDefaults为空的nx.json为例Before迁移前{ targetDefaults: {} }After迁移后{ targetDefaults: {}, useLegacyCache: true }迁移只追加useLegacyCache这一个顶级属性不会改动targetDefaults、affected、plugins等其他任何配置。测试用例验证两种分支行为均有覆盖仓库为这条迁移编写了完整的单元测试见 packages/nx/src/migrations/update-20-0-1/use-legacy-cache.spec.ts两个用例恰好覆盖上面的两个分支用例 1未配置enableDbCache的工作区迁移后写入useLegacyCache: trueit(should add useLegacyCache on migrating workspaces that did not have enableDbCache, async () { await update(tree); expect(readNxJson(tree)).toMatchInlineSnapshot( { affected: { defaultBase: main }, targetDefaults: { build: { cache: true }, lint: { cache: true }, }, useLegacyCache: true, } ); });用例 2配置过enableDbCache: true的工作区迁移后既不写useLegacyCache也删除了enableDbCacheit(should not add useLegacyCache on migrating workspaces that did have enableDbCache, async () { const nxJson readNxJson(tree); updateNxJson(tree, { enableDbCache: true, ...nxJson } as any); await update(tree); expect(readNxJson(tree)).toMatchInlineSnapshot( { affected: { defaultBase: main }, targetDefaults: { build: { cache: true }, lint: { cache: true }, }, } ); });这两组断言从测试层面印证了文档描述除非enableDbCache被显式设为 true否则迁移一律写入useLegacyCache。底层原理useLegacyCache背后的缓存双轨架构要真正理解useLegacyCache的作用需要看 Nx 20 运行时如何选择缓存实现。核心入口在 packages/nx/src/tasks-runner/cache.ts// Do not change the order of these arguments as this function is used by nx cloud export function getCache(options: DefaultTasksRunnerOptions): DbCache | Cache { const nxJson readNxJson(); return dbCacheEnabled() ? new DbCache({ // Remove this in Nx 21 nxCloudRemoteCache: isNxCloudUsed(nxJson) ? options.remoteCache : null, skipRemoteCache: options.skipRemoteCache, }) : new Cache(options); }dbCacheEnabled()决定走新缓存还是旧缓存在 cache.ts 中dbCacheEnabled()会检查两个条件若运行在 WASM 环境IS_WASM由于数据库缓存不受支持返回false走旧式缓存若用户设置了NX_REJECT_UNKNOWN_LOCAL_CACHE0或NX_REJECT_UNKNOWN_LOCAL_CACHEfalse环境变量Nx 会打印警告并告知该环境变量在新数据库缓存下不受支持此特性由 Nx Powerpack 提供类似能力同样回退到旧式缓存。其余情况返回true即 Nx 20 默认启用 DB Cache。可以看到useLegacyCache的作用本质上是让升级上来的工作区继续走dbCacheEnabled() false的旧式Cache路径从而保持与旧版本完全一致的缓存行为。DbCachevsCache新旧两套实现DbCachecache.ts在内部通过getDbConnection()建立数据库连接并实例化NxCacheRust 原生实现进行缓存读写同时支持NxCloud远程缓存检索Cachecache.ts是旧式实现其类注释明确标记/** * deprecated Use the {link DbCache} class instead. This will be removed in Nx 21. */ export class Cache { root workspaceRoot; cachePath this.createCacheDir(); terminalOutputsDir this.createTerminalOutputsDir(); ... }旧式Cache以文件目录cacheDir为核心缓存记录通过removeOldCacheRecords()定期清理Math.floor(Math.random() * 50) 1概率触发由独立的remove-old-cache-records.js子进程完成。运行时装配TaskOrchestrator 中的统一入口任务编排器在 packages/nx/src/tasks-runner/task-orchestrator.ts 中统一装配缓存实现export class TaskOrchestrator { private cache: DbCache | Cache getCache(this.options); ... }并且在实际执行任务时会再次检查dbCacheEnabled()以决定缓存命中结果是否标记为远程命中见 task-orchestrator.ts。nx report命令的缓存统计也依赖dbCacheEnabled()决定是否展示见 packages/nx/src/command-line/report/report.ts。由此可以确认一条完整链路nx.json中的useLegacyCache: true迁移写入→ 运行时缓存实现选择getCache→ 任务命中与产物恢复TaskOrchestrator。注意事项与边界情况迁移只针对nx.json顶级配置useLegacyCache是nx.json的顶级布尔属性与targetDefaults、affected等并列不嵌套在任何子对象下enableDbCache与useLegacyCache互斥前者存在时会被删除且不写后者两者永远不会同时出现在同一份nx.json中没有nx.json的工作区不会被修改迁移函数在读取不到配置时会安全退出该迁移不参与--repairx-repair-skip: true意味着即便后续运行修复命令也不会重复触发或干扰该迁移环境变量会影响实际缓存路径即使迁移写入了useLegacyCache: true运行时仍需满足dbCacheEnabled()的条件非 WASM、未设置NX_REJECT_UNKNOWN_LOCAL_CACHE0/false才会真正走旧式缓存。与 Nx 21 的衔接useLegacyCache的最终归宿useLegacyCache只是 Nx 20 的过渡机制不会长期存在。仓库中紧随其后的迁移remove-legacy-cache版本21.0.0-beta.8见 packages/nx/migrations.json会在升级到 Nx 21 时将其移除。该迁移的文档 packages/nx/src/migrations/update-21-0-0/remove-legacy-cache.md 说明RemovesuseLegacyCachefromnx.jsonas it is no longer functional in Nx 21其实现 packages/nx/src/migrations/update-21-0-0/remove-legacy-cache.ts 会直接删除nx.json中的useLegacyCache属性// If workspaces had useLegacyCache we can just delete the property // as the property is not functional in nx v21 if ((nxJson as any).useLegacyCache) { delete (nxJson as any).useLegacyCache; }对应变更示例BeforeNx 20 迁移后{ targetDefaults: {}, useLegacyCache: true }After升级到 Nx 21 后{ targetDefaults: {} }也就是说从旧版本一路升级到 Nx 21 的完整缓存配置路径是旧式缓存无标记→ Nx 20 写入useLegacyCache: true保持旧行为 → Nx 21 删除该标记全面切换到数据库缓存。手动配置建议如果你的工作区已升级到 Nx 20 但出于某种原因需要手动管理缓存行为可以按以下规则直接编辑nx.json保持旧式缓存行为写入useLegacyCache: true启用新数据库缓存Nx 20 默认删除useLegacyCache或不设置同时无需再配置已废弃的enableDbCache升级到 Nx 21 前主动删除useLegacyCache让工作区提前切换到数据库缓存避免升级时被迁移规则被动变更。小结useLegacyCache迁移use-legacy-cache是 Nx 20 缓存架构升级中的关键安全阀它以最小侵入方式仅追加一个顶级布尔属性为存量工作区保留了升级前的缓存行为同时自动清理已无意义的enableDbCache配置。理解这条迁移的分支逻辑enableDbCache有无之分、底层缓存选择链路dbCacheEnabled→getCache→DbCache/Cache以及它在 Nx 21 中的最终移除能让你在跨大版本升级时对缓存行为有完全的掌控力。【免费下载链接】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),仅供参考