?? 深入了解Nx受影響的部分
免费版本可在这里找到:https://gelinjo.hashnode.dev/
· 😵 这个项目为何受到影响?
· 🤓 受影响的提醒
∘ 受影响的项目
∘ 受影响的任务
· 🤩 受影响的命令
∘ 受影响的运行命令
∘ 显示指令
∘ Nx 图形
· 😶🌫️ 受影响的规则
∘ 步骤 1 - 查找已修改的文件
∘ 步骤 2.1 - 从路径查找受影响的节点
∘ 步骤 2.2 - 从任务查找受影响的节点
∘ 步骤 2.3 - 从插件查找受影响的节点
∘ 步骤 2.4 - 从 npm 依赖项查找受影响的节点
∘ 步骤 2.5 - 从 TypeScript 配置查找受影响的节点
∘ 步骤 2.6 - 从全局文件查找受影响的节点
∘ 步骤 3 - 生成受影响的图形
· 🧐 受影响的调查
∘ 使用 Nx 图形
∘ 调试
· 🤕 受影响的修复
∘ 良好的应用程序/库拆分
∘ 严格的命名输入
∘ 定制化受影响
∘ 修补 Nx
· 🙂 最后的想法
这是每天我都会被问到的问题!一个问题,它让我多次进入Nx Affected(Nx Affected 过程)的调试过程寻找答案。
本文将为您提供所有必要的信息和见解,帮助您了解Nx中受影响流程的工作方式,从而帮助您回答这个问题。
🤓 小提醒:受影响提示在单仓库中工作时,你会遇到一个包含多个应用和库的仓库。
随着您的单仓库越来越大,重建所有应用或库在持续集成中可能变得非常耗时。能够仅重新执行受影响的应用或库将大大缩短您的软件开发周期。
受影响的项目列表当你修改一个应用或库时,不仅会影响该应用或库,还会波及其他所有依赖它的应用或库。
Nx心智模型文档资料
为了理解应用程序和库之间的依赖关系,Nx 生成一个项目图,其中包括所有节点(应用和库)和外部节点(如npm),以及它们之间的所有依赖关系。
受影响的任务列表
仅仅考虑一个修改对整个应用程序或库的影响是不够的。例如,如果你在一个应用程序里修改了一个测试,这并不意味着你需要重新构建整个应用程序。只需要重新运行这个测试:
Nx心智模型说明文档
为了理解应用和库之间的任务依赖关系,Nx 生成了一个任务图(显示任务依赖关系),其中节点表示通过任务相互关联的项目。
🤩 这些受影响的命令Nx 提供了多种方法来确定哪些项目或任务受到影响。
受影响的运行情况通常在 CI 环境中用到的主要命令是Nx affected 命令(Nx 受影响命令),
nx 受影响的 -t lint 测试构建
使用此命令,您只能运行受影响的任务。
显示命令行另一个有用的Nx show 命令可以直接查看。
nx 列出项目 --affected
此命令让你能直接在控制台看到受影响的项目和任务,并将结果导出到一个 JSON
文件里,比如。
如果你需要一个 UI 视图,并且想要追踪受影响的项目或任务的路径,你可以使用以下命令打开Nx graph:
nx graph --受影响的
它将打开一个网页,你可以在那里看到一个类似于这样的图形。
Nx受影响的文件
😶🌫️ 迷茫中的规则受影响的Nx进程经过几个阶段,并查看各种文件和配置来判断哪些项目会被影响。
在计算受影响的项目列表之前,Nx 首先加载了已修改或涉及的文件列表。
Nx 通过计算自目标 Affected Base 以来所有被修改的文件来生成列表。
默认情况下,默认分支将是你的主分支,不过你可以通过 -base
和 -head
选项来更改默认分支。
所有尚未提交或跟踪的修改文件也将被加入。您可以使用-uncommitted
或-untracked
选项来自定义。
如果你不想让Nx来处理文件列表信息,你可以通过-files
选项提供你的列表。
匹配在 .gitignore
或 .nxignore
文件中模式的文件将被 忽略。
当所有涉及的文件被定义后,Nx 会看看这些文件对项目有什么影响。
最常见的情况是,检查文件路径是否和项目根路径一致。
步骤 2.2 - 查找任务中受影响的节点Nx还将间接影响一些项目,如果其中一个任务涉及的文件被修改了。
例如,如果你修改了一个像 jest.preset.ts
这样的全局 Jest 配置文件,因为它在相关的输入配置中被指定了,这也会影响到所有使用该执行程序的项目:
"targetDefaults": {
"@nx/jest:jest": {
"inputs": ["default", "^production", "{workspaceRoot}/jest.preset.js"], // "inputs" 是 Jest 配置中指定的输入项,包括默认值、生产环境标记和 Jest 预设文件路径。
},
},
每次当一个项目包含一个由被修改的文件影响的输入时,该项目将会受到影响。
有关Nx如何通过Inputs 、Named Inputs 和Outputs 进行目标缓存处理的更多详细信息,请参阅Nx文档_
步骤 2.3 - 查找受影响的节点来自插件
自从Nx Project Crystal推出和Nx插件采用推断配置以来,Nx也会检查插件是否受到修改文件列表的影响。
例如,如果你删除或移动了一个文件,Nx 会认为项目被删除了,并将所有相关项目标记为受到影响。
步骤 2.4 - 查找 Npm 依赖中的受影响模块如果修改了 package.json
文件,Nx 会采用一种智能方式来理解发生了什么变化。
如果你修改了一个 npm库(library),Nx 会找到所有使用该库的项目,并标记它们为受影响。如果是 @types/*
,Nx 会提取相关的库,并按照修改库时相同的原则进行处理。
如果你修改了 nx.json
插件中用到的库,或者删除了一个库,所有相关项目都会受到影响:
默认,修改 包管理锁定文件 这会影响所有项目。
你可以在nx.json
文件中通过修改projectsAffectedByDependencyUpdates
来调整这种行为。
"插件配置": {
"@nx/js": {
"受依赖更新影响的项目": "自动"
}
}
选项:
all
: 影响所有项目auto
: 仅影响与修改的依赖项相关的项目string[]
: 定义项目列表(例如:['项目1', '项目2'])
修改全局 TypeScript 配置项也会影响到受影响节点的列表范围。
如果修改了路径,Nx 会影响符合根路径的相关项目。然而,修改全局设置或删除路径会影响所有项目。
步骤 2.6 - 从全局配置文件中找到受影响的节点位置默认情况下,修改 nx.json
会会影响到所有项目。
识别所有受影响的节点后,Nx 创建一个受影响的节点图,以确定哪些nodes
,externalNodes
和dependencies
最终受到影响。
Nx 取出受影响的节点,然后在项目图中递归地搜索所有依赖关系。
例如,如果受影响的节点 lib10
被 lib4
引用了,并且 lib4
被 app1
引用,那么这些节点将全部加入受影响的项目图中。
Nx ,对 externalNodes
使用同样的原理:
例如,npm 库 enquirer
被另一个 npm 库 nx
所使用,而 nx
则被我们内部的 tools
库使用。
为了确保它是完整的,Nx还会加入相关的依赖
。
如果你还是不明白为什么一些项目在分支上受到影响,你可以随时查看Nx的affected命令。
当我们使用Nx Graph时,我们可以...如果你用那个受影响的命令打开Nx图,你就能看到受影响提醒部分所指定的所有那些受影响的项目。
你就可以探索你的工作区并使用比如项目焦点和依赖追踪器等多功能。
调试问题
然而,在大型代码库中,这张图通常很难用于调试。因此,我更喜欢通过调试受Nx影响的过程,来确切地找出是哪个步骤出了问题。
你可以从在 packages/nx/src/command-line/affected/affected.ts
文件中设置断点开始,并以调试模式运行 nx show project --affected
,.
自定义受影响的过程并不简单。如果您觉得每次修改后受影响的项目太多,这里有一些小建议:
合理拆分应用和库确保你的应用和库的拆分做得正确。
通常,共享库被多个项目共用,但其中的功能可能仅被一个项目使用。修改这样的库会波及所有项目。
严格的命名参数确保您的命名输入已正确设置。命名输入决定了修改文件是否会影响目标的输出结果。
例如,修改一个 spec 文件可能会影响测试,但不会影响构建。如果你使用默认命名输入,修改一个文件会波及你项目中的所有目标。
受影响的自定义目前,受影响的流程的自定义选项有限。您可以在更新依赖项时,通过配置 projectsAffectedByDependencyUpdates
来自定义(参阅步骤 2.4,从 Npm 依赖项查找受影响的节点)。
这是一个临时的解决方案,但我用它来定制受影响的过程。使用您的包管理器的补丁系统对您的Nx库进行调整可以改变既定规则。
你可以关闭“影响全部”用例,如下所示:
diff --git a/node_modules/nx/src/plugins/js/project-graph/affected/npm-packages.js b/node_modules/nx/src/plugins/js/project-graph/affected/npm-packages.js
index 72e78e7..7793bea 100644
--- a/node_modules/nx/src/plugins/js/project-graph/affected/npm-packages.js
+++ b/node_modules/nx/src/plugins/js/project-graph/affected/npm-packages.js
@@ -20,7 +20,8 @@ const getTouchedNpmPackages = (touchedFiles, _, nxJson, packageJson, projectGrap
c.path.length === 2) {
// 一个包被删除,所以标记所有工作区项目为已更改。
if (c.type === json_diff_1.JsonDiffType.Deleted) {
- touched = Object.keys(projectGraph.nodes);
+ // PATCH 不在删除包时影响所有项目
+ // touched = Object.keys(projectGraph.nodes);
break;
}
else {
diff --git a/node_modules/nx/src/plugins/js/project-graph/affected/tsconfig-json-changes.js b/node_modules/nx/src/plugins/js/project-graph/affected/tsconfig-json-changes.js
index bac7008..37ae136 100644
--- a/node_modules/nx/src/plugins/js/project-graph/affected/tsconfig-json-changes.js
+++ b/node_modules/nx/src/plugins/js/project-graph/affected/tsconfig-json-changes.js
@@ -24,7 +24,8 @@ const getTouchedProjectsFromTsConfig = (touchedFiles, _a, _b, _c, graph) => {
}
// 如果路径被删除,那么所有项目都会被标记为已更改。
if (change.type === json_diff_1.JsonDiffType.Deleted) {
- return Object.keys(graph.nodes);
+ // PATCH 不在删除路径时影响所有项目
+ // return Object.keys(graph.nodes);
}
touched.push(...getProjectsAffectedByPaths(change, Object.values(graph.nodes)));
}
diff --git a/node_modules/nx/src/project-graph/affected/affected-project-graph.js b/node_modules/nx/src/project-graph/affected/affected-project-graph.js
index 5665c8d..d5a69aa 100644
--- a/node_modules/nx/src/project-graph/affected/affected-project-graph.js
+++ b/node_modules/nx/src/project-graph/affected/affected-project-graph.js
@@ -12,7 +12,8 @@ async function filterAffected(graph, touchedFiles, nxJson = (0, configuration_1.
const touchedProjectLocators = [
workspace_projects_1.getTouchedProjects,
workspace_projects_1.getImplicitlyTouchedProjects,
- project_glob_changes_1.getTouchedProjectsFromProjectGlobChanges,
+ // PATCH 不在插件匹配更改文件时影响所有项目
+ // project_glob_changes_1.getTouchedProjectsFromProjectGlobChanges,
touched_projects_1.getTouchedProjects,
];
const touchedProjects = [];
diff --git a/node_modules/nx/src/project-graph/affected/locators/workspace-projects.js b/node_modules/nx/src/project-graph/affected/locators/workspace-projects.js
index c5aec64..edaa989 100644
--- a/node_modules/nx/src/project-graph/affected/locators/workspace-projects.js
+++ b/node_modules/nx/src/project-graph/affected/locators/workspace-projects.js
@@ -16,7 +16,8 @@ const getTouchedProjects = (touchedFiles, projectGraphNodes) => {
exports.getTouchedProjects = getTouchedProjects;
const getImplicitlyTouchedProjects = (fileChanges, projectGraphNodes, nxJson) => {
const implicits = {
- 'nx.json': '*',
+ // PATCH 不在更改 nx.json 时影响所有项目
+ // 'nx.json': '*',
};
Object.values(projectGraphNodes || {}).forEach((node) => {
const namedInputs = {
🙂 最后的感想
如您所见,Nx 受影响的处理过程不仅考虑了修改文件的列表,还会根据多种其他因素计算出项目列表。
这使得调查并不总是一帆风顺,并且常常会导致人人都受影响的状况。
我希望我已经澄清了一些部分,并帮助你更好地理解这部分内容。
我希望将来我们能为受影响的过程提供更多自定义选项,例如使类似 projectsAffectedByDependencyUpdates
的选项通用化,以这样的方式使我们有更多的自定义选项。
敬请期待
相关内容 The Nx 系列文章系列(由 jgelin 发布)
共同學習,寫下你的評論
評論加載中...
作者其他優質文章