Nx Gradle 插件迁移指南:将 dev.nx.gradle.project-graph 升级到 0.1.19
【免费下载链接】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 在22.7.0-beta.11版本中内置了一条自动迁移(Migration),用于将 Gradle 项目中的dev.nx.gradle.project-graph插件从0.1.18升级到0.1.19。本指南以 change-plugin-version-0-1-19.md 文档为核心,讲解这条迁移的用途、触发方式、底层实现原理,以及当自动迁移无法覆盖时的手动升级方案。阅读本文后,你将理解 Nx 如何通过迁移机制维护 Gradle 插件版本的一致性,并能独立完成该插件的版本升级与验证。
迁移背景:Nx 与 Gradle 项目图插件
Nx 通过@nx/gradle插件支持 Gradle 工作区的项目发现、依赖分析与任务编排。为了让 Nx 能识别 Gradle 工程结构并构建项目图(Project Graph),Gradle 构建脚本中需要声明一个配套的 Gradle 插件:
plugins { id "dev.nx.gradle.project-graph" version "0.1.18" }这个插件的版本与@nx/gradle插件之间存在对应关系,Nx 每次升级都会通过迁移将工作区内的 Gradle 插件版本同步到新版本。仓库中packages/gradle/src/migrations/目录下保存了从0.1.0一路到0.1.25的完整迁移链(例如 22-7-0 目录内就包含0.1.16至0.1.20五条迁移),而packages/gradle/src/utils/versions.ts中定义的gradleProjectGraphVersion当前值为0.1.25,说明后续版本仍在持续演进。
本篇文章聚焦的0.1.19迁移,对应 Nx 版本22.7.0-beta.11,其注册信息位于 migrations.json:
"change-plugin-version-0-1-19": { "version": "22.7.0-beta.11", "cli": "nx", "description": "Change dev.nx.gradle.project-graph to version 0.1.19 in build file", "factory": "./dist/src/migrations/22-7-0/change-plugin-version-0-1-19", "documentation": "./dist/src/migrations/22-7-0/change-plugin-version-0-1-19.md" }可以看到,该迁移由nxCLI 触发,factory指向迁移的实际执行代码,documentation指向本文所依据的说明文档。
迁移结果:Before / After 示例
迁移完成后的改动非常直观——仅替换plugins块中的插件版本号。原文档给出了标准示例:
Before
plugins { id "dev.nx.gradle.project-graph" version "0.1.18" }After
plugins { id "dev.nx.gradle.project-graph" version "0.1.19" }对于 Kotlin DSL 工程,对应的build.gradle.kts写法为:
plugins { id("dev.nx.gradle.project-graph") version "0.1.19" }如何触发这条迁移
该迁移通过 Nx 的migrate命令运行。在包含@nx/gradle插件且启用了 Gradle 支持的工作区中执行:
nx migrate @nx/gradleNx 会根据 migrations.json 中记录的版本信息,自动挑选并执行所有高于当前工作区版本的迁移,其中包括change-plugin-version-0-1-19。之后运行nx migrate --run-migrations应用生成的migrations.json文件,即可完成迁移。
migrations.json中每条迁移的"cli": "nx"字段表明它是由 Nx 自己的 migrate 流程调度的;如果你使用的是 Lerna,则需要通过nx migrate而不是 Lerna 命令来执行这类迁移。
源码级解析:迁移的内部执行流程
迁移的实际逻辑位于 change-plugin-version-0-1-19.ts,完整流程如下:
export default async function update(tree: Tree) { const nxJson = readNxJson(tree); if (!nxJson) { return; } if (!hasGradlePlugin(tree)) { return; } const gradlePluginVersionToUpdate = '0.1.19'; // 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。如果nx.json不存在,直接返回,不做任何改动。
随后调用hasGradlePlugin(定义于 has-gradle-plugin.ts)检查nx.json中的plugins配置是否包含@nx/gradle:
export function hasGradlePlugin(tree: Tree): boolean { const nxJson = readNxJson(tree); return !!nxJson.plugins?.some((p) => typeof p === 'string' ? p === '@nx/gradle' : p.plugin === '@nx/gradle' ); }只有当工作区确实启用了@nx/gradle插件时,迁移才会继续执行。这保证了迁移不会误伤未使用 Gradle 集成的普通 Nx 工作区。
第二步:更新 Version Catalog(libs.versions.toml)
迁移先通过updateNxPluginVersionInCatalogsAst处理版本目录。很多 Gradle 工程使用 Gradle Version Catalog(gradle/libs.versions.toml)统一管理依赖版本,例如:
[plugins] nx-project-graph = { id = "dev.nx.gradle.project-graph", version = "0.1.18" }该工具采用AST(抽象语法树)方式改写版本号,目的是在精确替换版本值的同时保留 TOML 文件的原有格式与注释,避免简单字符串替换带来的格式破坏。
第三步:更新 build.gradle(.kts) 文件
版本目录更新完成后,迁移调用addNxProjectGraphPlugin处理各build.gradle(.kts)文件。该函数位于 gradle-project-graph-plugin-utils.ts,其执行要点如下:
定位构建脚本:通过
globAsync查找工作区内所有**/settings.gradle与**/settings.gradle.kts文件,并在每个 settings 文件同级确保存在对应的build.gradle或build.gradle.kts(Kotlin DSL 工程为.kts后缀)。版本匹配正则:使用如下正则精确匹配插件声明:
const regex = /(id\s*\(?["']dev\.nx\.gradle\.project-graph["']\)?\s*version\s*\(?["'])([^"']+)(["']\)?)/;该正则同时兼容 Groovy DSL(
id "..." version "...")与 Kotlin DSL(id("...") version("..."))两种写法。就地替换:通过
updateNxPluginVersion将捕获到的旧版本号替换为0.1.19;若在文件中找不到插件声明,则会输出一条警告日志,提示用户手动更新。版本目录优先:
addNxProjectGraphPluginToBuildGradle会依次在构建脚本所在目录的gradle/libs.versions.toml、工作区根目录的gradle/libs.versions.toml以及子目录的任意libs.versions.toml中查找插件别名。若找到别名(如nx-project-graph),则构建脚本中会改用alias(libs.plugins.nx.project.graph)形式声明插件(别名中的连字符在 Gradle 访问器中转换为点号);此时版本号统一由版本目录管理,构建脚本本身不再出现版本字符串。幂等性保障:如果插件已存在但版本不同则只更新版本;如果插件已通过版本目录别名声明则跳过
allprojects重复应用逻辑,确保迁移重复执行不会产生重复的插件声明或多余的apply块。
手动升级:不依赖迁移命令的路径
如果你希望跳过nx migrate流程,或工作区结构特殊导致自动迁移未完全生效,可以按照以下步骤手动升级:
场景一:构建脚本中直接声明版本
编辑build.gradle(Groovy DSL):
plugins { id "dev.nx.gradle.project-graph" version "0.1.19" }或build.gradle.kts(Kotlin DSL):
plugins { id("dev.nx.gradle.project-graph") version "0.1.19" }场景二:使用 Version Catalog
编辑gradle/libs.versions.toml,将[plugins]下的版本值改为0.1.19:
[plugins] nx-project-graph = { id = "dev.nx.gradle.project-graph", version = "0.1.19" }若构建脚本中此前直接写死了版本号,则将其改为别名引用形式:
plugins { alias(libs.plugins.nx.project.graph) }升级后的验证
完成升级后,可通过以下方式验证:
- 检查版本声明:确认工作区内所有
build.gradle、build.gradle.kts及libs.versions.toml中的插件版本均为0.1.19。 - 运行构建:执行
./gradlew buildEnvironment --quiet,观察依赖树中dev.nx.gradle.project-graph:dev.nx.gradle.project-graph.gradle.plugin的版本是否为0.1.19——这也是迁移代码中getPluginVersion函数(位于 gradle-project-graph-plugin-utils.ts)用于兜底探测实际生效版本的方式。 - 验证 Nx 项目图:运行
nx graph或nx show projects,确认 Nx 仍能正确识别 Gradle 项目结构,说明插件升级后与@nx/gradle的集成工作正常。
结语
dev.nx.gradle.project-graph从0.1.18到0.1.19的升级是 Nx22.7.0系列中一次常规的插件版本同步迁移。从源码实现看,Nx 的迁移机制具备三项关键保障:通过nx.json前置校验避免误改无关工程;优先采用 AST 方式处理 Version Catalog 以保留格式;通过正则与别名检测保证构建脚本改写的幂等性。理解这条迁移的实现思路,也能帮助你预判后续每次 Gradle 插件版本升级(如仓库中已存在的0.1.20至0.1.25迁移)会如何作用于你的工作区。
【免费下载链接】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),仅供参考