ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

调试 Nx 缓存未命中(Cache Miss):用 Nx Cloud 对比任务运行、定位输入差异的完整排查指南

调试 Nx 缓存未命中(Cache Miss):用 Nx Cloud 对比任务运行、定位输入差异的完整排查指南 调试 Nx 缓存未命中Cache Miss用 Nx Cloud 对比任务运行、定位输入差异的完整排查指南【免费下载链接】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 官方课程 PNPM, Nx, and Next.js 的第 9 课《Debug Remote Cache misses with Nx Cloud》围绕 Nx 计算缓存系统中最常见也最棘手的问题——任务本应从缓存回放cache hit却总是重新执行cache miss——给出从项目配置检查到 Nx Cloud 任务对比工具的三步排查法。读完本文你将掌握如何确认任务是否真的被标记为可缓存、如何检查inputs/outputs配置是否被输出文件污染以及如何借助 Nx Cloud 的 Compare to similar tasks 功能逐项比对两次运行的哈希输入差异快速定位导致缓存失效的根因。课程背景为什么缓存命中率是 monorepo 提速的关键在 PNPM, Nx, and Next.js 这套课程中一个名为Tasker的 pnpm workspace 被逐步接入 Nx用pnpm nx build tasker/web取代pnpm --filter tasker/web build见第 2 课 Run and Manage Tasks Efficiently Using Nx配置.next目录的缓存输出见第 3 课 Configure Cache Outputs to Handle the .next Folder通过implicitDependencies建立 e2e 项目与 Web 应用的隐式依赖见第 5 课并将工作区接入 Nx Cloud 以获得远程缓存与分布式 CI 能力见第 6 课和第 8 课。而缓存命中率直接决定这一切优化的成效命中率越高本地与 CI 中重复执行的构建、测试就越少。理解是什么导致缓存未命中cache miss而非命中cache hit正是优化的关键前提——这正是本课的主题。先理解本质Nx 用什么判定这次运行该不该重跑在进入排查步骤前需要明确 Nx 缓存模型的两个基本事实依据仓库文档 Cache Task Results 与 Remote caching命中与未命中由输入哈希决定。Nx 会为每个任务计算一个哈希值该哈希由inputs以及namedInputs、环境变量等所圈定的所有内容共同决定。两次运行哈希一致 → 命中缓存Nx 直接恢复终端输出与outputs声明的产物文件如dist、build目录哈希不一致 → 缓存未命中任务被重新执行。远程缓存只是本地缓存的共享延伸。Nx 默认在本地缓存任务结果而 Nx Cloud 远程缓存让不同开发者机器与 CI 任务之间共享这些结果。远程缓存命中的行为与本地命中完全一致——直接恢复输出不再真正运行任务。因此所谓调试 cache miss本质是回答一个问题为什么这次运行的输入哈希与上次不同下面的三个检查步骤就是层层逼近这个答案的排查路径。检查 1任务是否真的被标记为 cacheable最容易被忽视的坑任务根本没有开启缓存自然每次都会老老实实执行。确认方式有两种查看 Project Details View 中的 Cacheable 标签。运行以下命令打开项目的详情视图nx show project project-name --web如果任务的配置详情里带有 Cacheable 标签说明该任务已启用缓存。直接检查任务的目标配置中是否设置了cache: true。该配置可以出现在项目级的project.json或package.json中的nx字段里也可以出现在工作区级的nx.json#targetDefaults中。例如在nx.json中统一为build与test开启缓存// nx.json { targetDefaults: { build: { cache: true }, test: { cache: true } } }可缓存任务的前提必须是无副作用的Nx 官方文档特别提醒见 Cache Task Results可缓存操作必须是无副作用的side effect free即给定相同输入永远产生相同输出。例如会真实访问后端 API 的 e2e 测试就不应缓存——后端状态可能影响测试结果若被缓存回放反而可能得到错误结论。同理凡是依赖外部状态时间、网络、随机数、环境等的任务都不适合标记为 cacheable。仓库实证本项目如何声明任务配置本仓库根目录的 nx.json 正是这种配置的完整范例其中的targetDefaults为各类任务声明了cache、inputs等属性例如为复制 README 的任务定义独立的copyReadme输入集。这说明cache: true只是第一步任务级配置通常还要搭配inputs一起使用见下一步。检查 2任务的输出是否在反向污染任务的输入确认任务已开启缓存但仍然每次重跑时下一步要审视inputs与outputs的配置依据 Troubleshoot Cache Missesinputs与namedInputs决定哈希、进而决定是否回放。它们定义了什么内容会参与任务哈希的计算——文件 glob、环境变量、运行时命令输出等。配置在项目级project.json或根nx.json中。outputs只决定回放哪些文件。它控制缓存命中时恢复哪些产物本身不决定是否命中。但危险在于一个未被outputs捕获的输出文件可能反过来修改了某个inputs所圈定的文件从而间接导致哈希变化、缓存失效。逐文件核对输入 glob 的方法要弄清输入 glob 到底匹配了哪些文件可以借助项目图nx graph --fileoutput.json运行后会在当前目录生成output.json其中包含每个项目关联的文件清单也可以在nx graph的可视化界面中点击任务图中的某个任务来查看其输入文件。通过它你可以逐一确认有没有一个文件既出现在输入里、又会被任务改动。典型场景把不会影响产物的文件排除出输入一个最常见的调优手法是排除无关文件避免它们参与哈希计算。例如希望修改README.md等 markdown 文件时不使构建缓存失效可以这样配置全局或项目级二选一// nx.json —— 全局统一配置 { targetDefaults: { build: { inputs: [{projectRoot}/**/*, !{projectRoot}/**/*.md], outputs: [{workspaceRoot}/dist/{projectName}] } } }// packages/some-project/project.json —— 项目级配置 { name: some-project, targets: { build: { inputs: [!{projectRoot}/**/*.md], outputs: [{workspaceRoot}/dist/apps/some-project] } } }{projectRoot}、{workspaceRoot}、{projectName}是 Nx 提供的占位符以!开头的 glob 表示排除。注意课程第 3 课曾强调Nx 默认能自动捕获dist、build等常见目录但.next目录不在默认捕获范围内需要像上面这样显式加入outputs详见课程 03-configure-cache。仓库实证namedInputs的真实组织方式本仓库根目录 nx.json 中的namedInputs展示了生产级工作区的典型做法namedInputs: { default: [{projectRoot}/**/*, sharedGlobals], production: [ default, !{projectRoot}/**/?(*.)(spec|test).[jt]s?(x)?(.snap), !{projectRoot}/tsconfig.spec.json, !{projectRoot}/jest.config.[jt]s, !{projectRoot}/eslint.config.(js|cjs|mjs|ts|cts|mts), !{projectRoot}/.storybook/**/*, !{projectRoot}/**/*.stories.(js|jsx|ts|tsx|mdx), !{projectRoot}/tsconfig.storybook.json, !{projectRoot}/src/test-setup.[jt]s ], sharedGlobals: [ {workspaceRoot}/babel.config.json, {workspaceRoot}/.nx/workflows/agents.yaml, {workspaceRoot}/.github/workflows/ci.yml ] }从中可以看到三个可复用的设计模式命名输入可被其他命名输入引用production以default为基础再叠加排除规则default又引用了sharedGlobals形成层级组合用排除规则剥离开发态文件测试文件、tsconfig.spec.json、jest.config、eslint 配置、storybook 文件等被从production输入中剔除——因为生产构建不依赖它们让它们参与哈希只会徒增缓存失效跨项目共享的全局输入sharedGlobals把工作区级的构建配置如babel.config.json、CI 配置等放入所有任务的公共输入任何一处变更都会正确触发下游任务重跑。这种default / production / sharedGlobals的分层结构正是避免输出污染输入、让哈希计算既准确又精简的工程化实践。检查 3使用 Nx Cloud 调试工具对比两次运行前两步确认配置无误后就可以借助 Nx Cloud 的对比工具来精确定位到底是哪个输入变了。这是本课的核心实操环节完整步骤如下依据 Troubleshoot Cache Misses确保仓库已连接 Nx Cloud。若尚未连接可运行npx nxlatest connect完成接入详见 Remote caching 文档。Nx Cloud 提供内置的托管式远程缓存并支持通过访问令牌Access Tokens精细控制 CI 对缓存的读写权限这正是课程第 8 课所讲的内容。点击终端中打印的 run details 链接。每次运行任务后Nx 都会在终端输出一条指向该次运行的链接打开后你可以按缓存状态cache status搜索和过滤任务快速筛选出发生 cache miss 的那条任务。打开任务详情面板点击Compare to similar tasks按钮。选择要对比的基准运行从 Compared to 区域的相似任务列表中选择一条或直接粘贴一条 run URL来与指定运行对比。查看哈希输入差异Nx Cloud 会对比两条任务运行的哈希输入并高亮所有差异项使哪个输入发生了变化一目了然。关键局限Nx Cloud 只能告诉你输入不同不能告诉你源码怎么不同官方文档对此有一条重要说明见 Troubleshoot Cache MissesNx Cloud 无法访问你的源代码因此它只能基于已保存的内容哈希告诉你哪些输入不同而无法给出源码的精确 git diff。这意味着排查思路应是先用 Nx Cloud 锁定是哪一组输入哪个文件、哪类 glob、哪个环境变量发生变化再回到本地用git diff等工具确认该输入的具体改动内容。两者配合才能完成从输入变了到为什么变了的完整定位。完整的排查路径速查综合本课内容当你在本地或 CI 中遇到任务本应回放却被重新执行时可按以下顺序自检步骤检查点验证方式1任务是否已开启缓存nx show project project-name --web查看 Cacheable 标签确认project.json或nx.json#targetDefaults中cache: true2任务的输入与输出是否配置正确核对inputs/namedInputs是否圈住了所有真正影响产物的文件确认outputs覆盖了所有产物目录如.next用nx graph --fileoutput.json逐文件核对3哪组输入发生了变化连接 Nx Cloud 后打开 run details 链接 → 按缓存状态过滤 → 打开任务详情 → Compare to similar tasks → 对比哈希输入差异高亮处即根因所在深入学习仓库中可继续研读的相关资料本文的权威排查原文Troubleshoot Cache Misses缓存系统概念与inputs/outputs精调Cache Task Results远程缓存的原理、安全与 CI 集成Remote caching本仓库的namedInputs/targetDefaults完整配置范例nx.json课程配套的缓存配置课时03-configure-cache.md、08-remote-caching.md【免费下载链接】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),仅供参考
返回列表