Nx 23.1.0 Gradle 迁移指南:将 dev.nx.gradle.project-graph 升级到 0.1.23
【免费下载链接】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包中内置的自动迁移器,讲解如何将 Gradle 构建文件中的dev.nx.gradle.project-graph插件从 0.1.22 升级到 0.1.23。读完本文,你将了解这条迁移在nx migrate流程中如何被触发、它修改了哪些文件、底层正则与 AST 解析的实现原理,以及当构建脚本使用版本目录(Version Catalog)时迁移器如何保持格式不变地完成替换。
迁移背景:版本升级为什么需要自动迁移
dev.nx.gradle.project-graph是 Nx 官方发布的 Gradle 插件,用于在 Nx 的项目图中集成 Gradle 工程。随着插件持续迭代(本仓库内从 0.1.0 一路升级到 0.1.25),Nx 会在每个版本中附带一个对应的迁移器,保证用户工作区中的插件版本始终与当前 Nx 版本兼容。
本次迁移对应 Nx 23.1.0 版本。在 packages/gradle/migrations.json 中可以看到它的注册信息:
"change-plugin-version-0-1-23": { "version": "23.1.0-beta.4", "cli": "nx", "description": "Change dev.nx.gradle.project-graph to version 0.1.23 in build file", "factory": "./dist/src/migrations/23-1-0/change-plugin-version-0-1-23", "documentation": "./dist/src/migrations/23-1-0/change-plugin-version-0-1-23.md" }它属于cli: "nx"类型的迁移,意味着执行nx migrate时会被自动应用,无需手动干预。
自动迁移:如何执行与触发条件
在启用了@nx/gradle插件的工作区中,升级到 Nx 23.1.0 并运行:
nx migrate @nx/gradle@23.1.0 nx migrate --run-migrations迁移器会自动扫描并更新所有 Gradle 构建文件。但需要注意,它的执行是有前置条件的。从迁移实现 change-plugin-version-0-1-23.ts 可以看到,迁移器会先做两次"短路判断":
- 工作区必须存在
nx.json:readNxJson(tree)返回空时直接返回,不做任何修改; - 工作区必须启用了
@nx/gradle插件:通过 has-gradle-plugin.ts 检查nx.json的plugins数组中是否包含字符串形式的"@nx/gradle"或对象形式的{ plugin: "@nx/gradle" }。
只有当这两项都满足时,才真正开始版本更新:
const gradlePluginVersionToUpdate = '0.1.23'; // 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);更新分两步执行:先更新版本目录(libs.versions.toml),再更新 build.gradle(.kts) 文件,顺序上保证版本目录中的version.ref被正确指向新版本后,构建文件中的引用不会产生不一致。
手动修改:Before / After 对照
如果你选择不运行自动迁移,也可以手动修改构建文件。迁移文档给出的示例针对 Groovy DSL:
Before(升级前)— build.gradle:
plugins { id "dev.nx.gradle.project-graph" version "0.1.22" }After(升级后):
plugins { id "dev.nx.gradle.project-graph" version "0.1.23" }底层实现:build.gradle(.kts) 是如何被改写的
对于 Groovy 与 Kotlin DSL 两种构建脚本,迁移器复用了 gradle-project-graph-plugin-utils.ts 中的逻辑。核心机制是一个正则表达式:
const regex = /(id\s*\(?["']dev\.nx\.gradle\.project-graph["']\)?\s*version\s*\(?["'])([^"']+)(["']\)?)/;该正则同时兼容两种 DSL 写法:
- Groovy:
id "dev.nx.gradle.project-graph" version "0.1.22" - Kotlin:
id("dev.nx.gradle.project-graph") version("0.1.22")
匹配后通过updateNxPluginVersion用content.replace(regex,$1${newVersion}$3)精确替换版本号,保持插件声明前后语法不变。若构建文件中找不到匹配,会输出一条日志提示手动更新:
Please update plugin dev.nx.gradle.project-graph to 0.1.23迁移的目标文件通过addBuildGradleFileNextToSettingsGradle定位:它使用 glob 匹配**/settings.gradle和**/settings.gradle.kts,并在每个 settings 文件同目录下寻找对应的build.gradle或build.gradle.kts。这意味着多模块工作区中所有 Gradle 工程都会同步更新。
从测试用例 change-plugin-version-0-1-12.spec.ts(同一系列迁移的验证样板)可以确认以下行为:
- Groovy DSL 与 Kotlin DSL 的插件声明都能被正确改写;
- 存在多个
build.gradle文件时全部更新; - 缺少
nx.json时不做任何修改; - 未启用
@nx/gradle插件时不修改构建文件。
版本目录(Version Catalog):三种格式的 AST 级更新
如果项目使用 Gradle Version Catalog(gradle/libs.versions.toml)管理插件版本,迁移器会先通过 version-catalog-ast-utils.ts 处理。它使用toml-eslint-parser将 TOML 解析为 AST,再基于 AST 节点的range做定点替换,从而完整保留原始格式(包括注释、缩进与引号风格)。
findVersionCatalogFiles通过 glob 搜索**/gradle/*.versions.toml找出所有目录文件。对于目录中声明的dev.nx.gradle.project-graph插件,支持三种书写格式:
格式一:简单格式(simple)
[plugins] nx-graph = "dev.nx.gradle.project-graph:0.1.22"迁移后:nx-graph = "dev.nx.gradle.project-graph:0.1.23",并保持单双引号风格不变。
格式二:内联表 + 直接版本(object with version)
[plugins] nx-graph = { id = "dev.nx.gradle.project-graph", version = "0.1.22" }迁移后:version = "0.1.23"。
格式三:内联表 + 版本引用(object with version.ref)
[versions] nx-project-graph = "0.1.22" [plugins] nx-graph = { id = "dev.nx.gradle.project-graph", version.ref = "nx-project-graph" }此时迁移器不会改动[plugins]段,而是顺着version.ref找到[versions]表中对应的版本键,把nx-project-graph = "0.1.22"更新为"0.1.23",确保引用关系始终有效。
目录文件的搜索顺序(见findVersionCatalogPluginAlias):先查构建文件同级的gradle/libs.versions.toml,再查工作区根的gradle/libs.versions.toml,最后递归搜索构建文件子目录下的所有libs.versions.toml。若插件通过目录别名声明,addNxProjectGraphPluginToBuildGradle还会把构建文件中的声明改写为alias(libs.plugins.xxx)形式(别名中的短横线会转换为点号访问器,如nx-project-graph→libs.plugins.nx.project.graph),实现单点管理版本。
迁移后的验证与常见问题
升级完成后,可以按以下方式确认迁移生效:
# 在构建文件所在目录执行,查看插件实际解析版本 ./gradlew buildEnvironment --quiet | grep project-graph该命令与迁移器内部的兜底逻辑一致:当build.gradle中无法通过正则匹配到版本时,迁移器会执行buildEnvironment --quiet并从依赖树中解析dev.nx.gradle.project-graph:dev.nx.gradle.project-graph.gradle.plugin:<version>的实际版本(见extractNxPluginVersion/getPluginVersion)。
常见注意事项:
- Kotlin DSL 无需特殊处理:
build.gradle.kts中的id("...") version("...")写法同样被正则覆盖; - 多工程工作区:所有存在
settings.gradle(.kts)的目录都会参与更新,可对照测试中的多文件场景验证; - 版本目录与直接声明共存:迁移会同时处理目录与构建文件,两者最终版本保持一致;
- 提前退出:没有
nx.json或未启用@nx/gradle插件的工作区,迁移器直接返回,构建文件不会被误改。
小结
dev.nx.gradle.project-graph0.1.22 → 0.1.23 的升级迁移是 Nx 23.1.0 自动迁移体系中的一个典型示例:先校验工作区与插件启用状态,再通过正则精确改写 Groovy/Kotlin DSL 构建文件,并通过 TOML AST 定点替换优雅处理三种版本目录格式。理解这一迁移的实现(change-plugin-version-0-1-23.ts)与其复用工具(gradle-project-graph-plugin-utils.ts、version-catalog-ast-utils.ts),不仅能帮助你顺利升级,也能让你在后续遇到 0.1.24、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),仅供参考