
Nx 迁移机制实战将 dev.nx.gradle.project-graph 插件升级到 0.1.22【免费下载链接】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 仓库中nx/gradle包自带的自动化迁移migration如何将 Gradle 构建文件中的dev.nx.gradle.project-graph插件版本从 0.1.21 升级到 0.1.22。文章以迁移说明文档 change-plugin-version-0-1-22.md 为主体深入解析其底层实现AST 级版本目录更新、build.gradle 正则改写、Gradle 命令行回退探测并结合 Nx 迁移注册机制帮助读者理解并掌握 Nx 中 Gradle 插件版本管理的完整工作方式。背景为什么 Gradle 插件版本需要随 Nx 同步升级在 Nx 的 Gradle 集成方案中dev.nx.gradle.project-graph是一个关键的 Gradle 插件它负责在 Gradle 构建时生成项目图project graph数据供nx/gradle插件即packages/gradle/src/plugin/nodes.ts与plugin/dependencies.ts中的 createNodes / createDependencies 实现消费从而让 Nx 能够识别 Gradle 模块、任务与依赖关系实现构建缓存、任务编排与 CI 优化。由于 Nx 侧与 Gradle 插件侧需要保持协议兼容插件版本必须与 Nx 版本配套。为此Nx 为每个新版本内置了一个迁移migration当工作区从旧版 Nx 升级时迁移会自动把构建文件中的插件版本改写为目标版本。本文要讲解的change-plugin-version-0-1-22正是这一系列版本迁移中的一个节点——它将插件从 0.1.21 提升到 0.1.22。迁移说明文档解读一次最小化的版本替换关联文档位于 packages/gradle/src/migrations/23-0-0/change-plugin-version-0-1-22.md其内容非常聚焦将build.gradle中的插件版本改为 0.1.22。文档给出了迁移前后的标准示例迁移前Beforeplugins { id dev.nx.gradle.project-graph version 0.1.21 }迁移后Afterplugins { id dev.nx.gradle.project-graph version 0.1.22 }这是 Nx 迁移文档的标准模板先一句 Change dev.nx.gradle.project-graph to version 0.1.22 in build file 概括目标再用 before/after 代码块明确展示期望的改动结果。实际执行时这一改动并不需要手工完成而是由迁移实现change-plugin-version-0-1-22.ts自动写入。迁移的注册机制migrations.json 中的声明任何迁移要生效都必须在包的migrations.json中注册。在 packages/gradle/migrations.json 中可以找到本迁移的声明change-plugin-version-0-1-22: { version: 23.0.0-rc.2, cli: nx, description: Change dev.nx.gradle.project-graph to version 0.1.22 in build file, factory: ./dist/src/migrations/23-0-0/change-plugin-version-0-1-22, documentation: ./dist/src/migrations/23-0-0/change-plugin-version-0-1-22.md }关键字段的含义version23.0.0-rc.2表示当工作区从早于该版本的 Nx 升级到23.0.0-rc.2或更高版本时该迁移会被触发。clinx表示该迁移面向 Nx CLI 生态区别于面向独立包的迁移。factory指向编译后的迁移实现即 TS 源码 change-plugin-version-0-1-22.ts。documentation指向说明文档也就是我们上面读到的 .md 文件。Nx 的迁移框架会读取这份清单在nx migrate流程中按版本顺序逐个执行符合条件的迁移并将说明文档呈现给用户审阅。迁移实现源码解析三步完成版本更新迁移的实际逻辑非常简洁完整代码如下change-plugin-version-0-1-22.tsimport { Tree, readNxJson } from nx/devkit; import { hasGradlePlugin } from ../../utils/has-gradle-plugin; import { addNxProjectGraphPlugin } from ../../generators/init/gradle-project-graph-plugin-utils; import { updateNxPluginVersionInCatalogsAst } from ../../utils/version-catalog-ast-utils; export default async function update(tree: Tree) { const nxJson readNxJson(tree); if (!nxJson) { return; } if (!hasGradlePlugin(tree)) { return; } const gradlePluginVersionToUpdate 0.1.22; // Update version in version catalogs using AST-based approach to preserve formatting await updateNxPluginVersionInCatalogsAst(tree, gradlePluginVersionToUpdate); // Then update in build.gradle(.kts) files await addNxProjectGraphPlugin(tree, gradlePluginVersionToUpdate); }第一步前置条件检查迁移首先通过readNxJson(tree)读取工作区根目录的nx.json若不存在则直接返回。随后调用hasGradlePluginhas-gradle-plugin.ts检查nx.json的plugins配置中是否声明了nx/gradleexport function hasGradlePlugin(tree: Tree): boolean { const nxJson readNxJson(tree); return !!nxJson.plugins?.some((p) typeof p string ? p nx/gradle : p.plugin nx/gradle ); }这保证了迁移只对真正启用了 Gradle 集成的 Nx 工作区生效——如果你的项目没有用到nx/gradle迁移会安静地跳过不会产生任何副作用。从源码结构看这里同时兼容了字符串形式plugins: [nx/gradle]与对象形式plugins: [{ plugin: nx/gradle, ... }]两种配置写法。第二步用 AST 方式更新版本目录libs.versions.toml对于使用 Gradle Version Catalog 的工作区插件版本通常定义在gradle/libs.versions.toml中而不是直接写在 build 文件里。迁移调用updateNxPluginVersionInCatalogsAstversion-catalog-ast-utils.ts来完成这一部分通过globAsync(tree, [**/gradle/*.versions.toml])找到工作区中所有版本目录文件用extractPluginVersionFromCatalogAst解析当前插件版本若与目标版本 0.1.22 不同则继续调用updatePluginVersionInCatalogAst基于toml-eslint-parser生成 TOML AST精确定位需要替换的 token 区间range再做字符串切片重建。之所以采用 AST 而非简单字符串替换源码注释明确说明是为了 preserve formatting保留原格式。该工具函数支持三种版本目录写法简单格式nx-project-graph dev.nx.gradle.project-graph:0.1.21会替换为...:0.1.22且会保留原引号风格双引号或单引号对象格式直接版本nx-project-graph { id dev.nx.gradle.project-graph, version 0.1.21 }只替换version的值对象格式version.ref 引用nx-project-graph { id dev.nx.gradle.project-graph, version.ref nxProjectGraph }此时会追查到[versions]表中的nxProjectGraph 0.1.21并更新它同时兼容带引号的version.ref键写法。第三步更新 build.gradle / build.gradle.kts 文件版本目录更新完成后迁移调用addNxProjectGraphPlugingradle-project-graph-plugin-utils.ts处理直接写在 build 文件里的插件声明。其内部逻辑覆盖了多种场景定位目标文件。通过addBuildGradleFileNextToSettingsGradle用 glob 匹配所有**/settings.gradle与**/settings.gradle.kts在每个 settings 文件同目录下确定对应的build.gradleGroovy DSL或build.gradle.ktsKotlin DSL。版本改写。对已存在插件声明的文件用正则匹配两种声明风格gradle-project-graph-plugin-utils.ts#L52-L53const regex /(id\s*\(?[]dev\.nx\.gradle\.project-graph[]\)?\s*version\s*\(?[])([^])([]\)?)/;这一正则可以同时匹配 Groovy 的id dev.nx.gradle.project-graph version 0.1.21与 Kotlin DSL 的id(dev.nx.gradle.project-graph) version(0.1.21)。匹配成功后updateNxPluginVersion通过content.replace(regex,$1${newVersion}$3)完成版本替换若未匹配到则输出一条 warn 日志提示手工更新Please update plugin dev.nx.gradle.project-graph to 0.1.22兜底探测。如果正则无法从 build 文件中提取出版本例如插件版本来自插件管理仓库extractNxPluginVersion会尝试在gradlew buildEnvironment --quiet命令输出中查找形如dev.nx.gradle.project-graph:dev.nx.gradle.project-graph.gradle.plugin:version的行来解析当前版本gradle-project-graph-plugin-utils.ts确认版本不一致后才改写。version catalog 别名支持。若 build 文件通过alias(libs.plugins.nx.project.graph)引用插件别名中的连字符在 Gradle 访问器中会转为点号迁移会先在标准位置build 文件同级gradle/libs.versions.toml、工作区根gradle/libs.versions.toml以及任意子目录的libs.versions.toml中查找插件别名识别出别名后跳过直接声明避免重复注入。allprojects 传播。若插件未通过别名应用迁移还会确保每个 build 文件的allprojects块中应用了该插件Groovy 用plugin dev.nx.gradle.project-graphKotlin DSL 用plugin(dev.nx.gradle.project-graph)并做了幂等处理——重复执行不会追加重复的 apply 语句。插件版本升级的演进脉络0.1.21 → 0.1.22只是 Nx 维护插件版本长期演进中的一个环节。从 packages/gradle/migrations.json 的迁移清单可以看到一条清晰的升级链0.1.021.1.2→0.1.221.3.0→0.1.421.3.11→0.1.521.4.0→0.1.621.4.1→0.1.721.5.1→0.1.821.6.1→0.1.922.1.0→0.1.1022.2.0→0.1.1122.3.0→0.1.1222.5.0→0.1.1322.5.3→0.1.14/0.1.1522.6.0→0.1.16至0.1.2022.7.0→0.1.21与0.1.2223.0.0→0.1.23/0.1.2423.1.0→0.1.2523.2.0。每个版本点都对应一个独立的迁移实现change-plugin-version-0-1-XX.ts与说明文档同名.md实现逻辑高度同构仅目标版本号不同。而packages/gradle/src/utils/versions.ts中定义的gradleProjectGraphVersion 0.1.25则作为当前仓库的默认插件版本供nx/gradle的 init 生成器在新建工作区时直接采用。从这一演进模式可以推断Nx 团队会随 Nx 版本迭代定期发布 Gradle 插件补丁版本并以迁移机制保证既有工作区平滑跟进用户在升级 Nx 时无需记忆每个插件的版本号。如何让迁移生效在升级 Nx 时自动执行这份迁移文档面向的是使用nx migrate升级工作区的用户。典型流程如下在包含nx.json与package.json的工作区根目录运行nx migrate latestNx 会解析各插件的migrations.json生成migrations.json工作区级迁移计划文件运行nx migrate --run-migrationsNx 按版本顺序执行所有待执行迁移——其中就包括change-plugin-version-0-1-22自动完成build.gradle、build.gradle.kts与gradle/libs.versions.toml中插件版本的改写迁移执行后nx migrate --run-migrations会移除迁移计划文件此时可以运行./gradlew help或nx graph验证插件 0.1.22 已正常加载。由于迁移实现本身具有幂等性重复执行不会重复追加或产生格式损坏即使迁移中断后重跑也是安全的。注意事项与排查要点迁移的前置条件只有nx.json存在且plugins中声明了nx/gradle时迁移才会改写文件如果确认工作区启用了 Gradle 集成但版本未更新请检查nx.json的插件配置是否为字符串形式或对象形式。版本目录优先如果同时在libs.versions.toml与 build 文件中声明了插件迁移会先更新版本目录AST 方式再更新 build 文件建议把版本集中管理在 version catalog 中避免两处不一致。Kotlin DSL 同样支持虽然说明文档只展示了 Groovy DSL 的 before/after 示例但实现层面gradle-project-graph-plugin-utils.ts对build.gradle.kts的id(dev.nx.gradle.project-graph) version(0.1.22)写法有同等支持。无法自动识别时的降级路径当版本声明方式超出正则与 AST 的覆盖范围时迁移会打印 warn 日志提示手工更新此时可对照本文 before/after 示例在 build 文件中手动将版本改为0.1.22。保持配套插件版本应与 Nx 版本保持配套当前仓库默认版本为 0.1.25见 versions.ts。若后续升级到更新版本Nx 会继续提供change-plugin-version-0-1-2X系列的迁移来跟进。【免费下载链接】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),仅供参考