試 Nx 緩存未命中(Cache Miss):用 Nx Cloud 對比任務(wù)運(yùn)行、定位輸入差異的完整排查指南)
調(diào)試 Nx 緩存未命中Cache Miss用 Nx Cloud 對比任務(wù)運(yùn)行、定位輸入差異的完整排查指南【免費(fèi)下載鏈接】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 計算緩存系統(tǒng)中最常見也最棘手的問題——任務(wù)本應(yīng)從緩存回放cache hit卻總是重新執(zhí)行cache miss——給出從項目配置檢查到 Nx Cloud 任務(wù)對比工具的三步排查法。讀完本文你將掌握如何確認(rèn)任務(wù)是否真的被標(biāo)記為可緩存、如何檢查inputs/outputs配置是否被輸出文件污染以及如何借助 Nx Cloud 的 Compare to similar tasks 功能逐項比對兩次運(yùn)行的哈希輸入差異快速定位導(dǎo)致緩存失效的根因。課程背景為什么緩存命中率是 monorepo 提速的關(guān)鍵在 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 應(yīng)用的隱式依賴見第 5 課并將工作區(qū)接入 Nx Cloud 以獲得遠(yuǎn)程緩存與分布式 CI 能力見第 6 課和第 8 課。而緩存命中率直接決定這一切優(yōu)化的成效命中率越高本地與 CI 中重復(fù)執(zhí)行的構(gòu)建、測試就越少。理解是什么導(dǎo)致緩存未命中cache miss而非命中cache hit正是優(yōu)化的關(guān)鍵前提——這正是本課的主題。先理解本質(zhì)Nx 用什么判定這次運(yùn)行該不該重跑在進(jìn)入排查步驟前需要明確 Nx 緩存模型的兩個基本事實(shí)依據(jù)倉庫文檔 Cache Task Results 與 Remote caching命中與未命中由輸入哈希決定。Nx 會為每個任務(wù)計算一個哈希值該哈希由inputs以及namedInputs、環(huán)境變量等所圈定的所有內(nèi)容共同決定。兩次運(yùn)行哈希一致 → 命中緩存Nx 直接恢復(fù)終端輸出與outputs聲明的產(chǎn)物文件如dist、build目錄哈希不一致 → 緩存未命中任務(wù)被重新執(zhí)行。遠(yuǎn)程緩存只是本地緩存的共享延伸。Nx 默認(rèn)在本地緩存任務(wù)結(jié)果而 Nx Cloud 遠(yuǎn)程緩存讓不同開發(fā)者機(jī)器與 CI 任務(wù)之間共享這些結(jié)果。遠(yuǎn)程緩存命中的行為與本地命中完全一致——直接恢復(fù)輸出不再真正運(yùn)行任務(wù)。因此所謂調(diào)試 cache miss本質(zhì)是回答一個問題為什么這次運(yùn)行的輸入哈希與上次不同下面的三個檢查步驟就是層層逼近這個答案的排查路徑。檢查 1任務(wù)是否真的被標(biāo)記為 cacheable最容易被忽視的坑任務(wù)根本沒有開啟緩存自然每次都會老老實(shí)實(shí)執(zhí)行。確認(rèn)方式有兩種查看 Project Details View 中的 Cacheable 標(biāo)簽。運(yùn)行以下命令打開項目的詳情視圖nx show project project-name --web如果任務(wù)的配置詳情里帶有 Cacheable 標(biāo)簽說明該任務(wù)已啟用緩存。直接檢查任務(wù)的目標(biāo)配置中是否設(shè)置了cache: true。該配置可以出現(xiàn)在項目級的project.json或package.json中的nx字段里也可以出現(xiàn)在工作區(qū)級的nx.json#targetDefaults中。例如在nx.json中統(tǒng)一為build與test開啟緩存// nx.json { targetDefaults: { build: { cache: true }, test: { cache: true } } }可緩存任務(wù)的前提必須是無副作用的Nx 官方文檔特別提醒見 Cache Task Results可緩存操作必須是無副作用的side effect free即給定相同輸入永遠(yuǎn)產(chǎn)生相同輸出。例如會真實(shí)訪問后端 API 的 e2e 測試就不應(yīng)緩存——后端狀態(tài)可能影響測試結(jié)果若被緩存回放反而可能得到錯誤結(jié)論。同理凡是依賴外部狀態(tài)時間、網(wǎng)絡(luò)、隨機(jī)數(shù)、環(huán)境等的任務(wù)都不適合標(biāo)記為 cacheable。倉庫實(shí)證本項目如何聲明任務(wù)配置本倉庫根目錄的 nx.json 正是這種配置的完整范例其中的targetDefaults為各類任務(wù)聲明了cache、inputs等屬性例如為復(fù)制 README 的任務(wù)定義獨(dú)立的copyReadme輸入集。這說明cache: true只是第一步任務(wù)級配置通常還要搭配inputs一起使用見下一步。檢查 2任務(wù)的輸出是否在反向污染任務(wù)的輸入確認(rèn)任務(wù)已開啟緩存但仍然每次重跑時下一步要審視inputs與outputs的配置依據(jù) Troubleshoot Cache Missesinputs與namedInputs決定哈希、進(jìn)而決定是否回放。它們定義了什么內(nèi)容會參與任務(wù)哈希的計算——文件 glob、環(huán)境變量、運(yùn)行時命令輸出等。配置在項目級project.json或根nx.json中。outputs只決定回放哪些文件。它控制緩存命中時恢復(fù)哪些產(chǎn)物本身不決定是否命中。但危險在于一個未被outputs捕獲的輸出文件可能反過來修改了某個inputs所圈定的文件從而間接導(dǎo)致哈希變化、緩存失效。逐文件核對輸入 glob 的方法要弄清輸入 glob 到底匹配了哪些文件可以借助項目圖nx graph --fileoutput.json運(yùn)行后會在當(dāng)前目錄生成output.json其中包含每個項目關(guān)聯(lián)的文件清單也可以在nx graph的可視化界面中點(diǎn)擊任務(wù)圖中的某個任務(wù)來查看其輸入文件。通過它你可以逐一確認(rèn)有沒有一個文件既出現(xiàn)在輸入里、又會被任務(wù)改動。典型場景把不會影響產(chǎn)物的文件排除出輸入一個最常見的調(diào)優(yōu)手法是排除無關(guān)文件避免它們參與哈希計算。例如希望修改README.md等 markdown 文件時不使構(gòu)建緩存失效可以這樣配置全局或項目級二選一// nx.json —— 全局統(tǒng)一配置 { 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 課曾強(qiáng)調(diào)Nx 默認(rèn)能自動捕獲dist、build等常見目錄但.next目錄不在默認(rèn)捕獲范圍內(nèi)需要像上面這樣顯式加入outputs詳見課程 03-configure-cache。倉庫實(shí)證namedInputs的真實(shí)組織方式本倉庫根目錄 nx.json 中的namedInputs展示了生產(chǎn)級工作區(qū)的典型做法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 ] }從中可以看到三個可復(fù)用的設(shè)計模式命名輸入可被其他命名輸入引用production以default為基礎(chǔ)再疊加排除規(guī)則default又引用了sharedGlobals形成層級組合用排除規(guī)則剝離開發(fā)態(tài)文件測試文件、tsconfig.spec.json、jest.config、eslint 配置、storybook 文件等被從production輸入中剔除——因?yàn)樯a(chǎn)構(gòu)建不依賴它們讓它們參與哈希只會徒增緩存失效跨項目共享的全局輸入sharedGlobals把工作區(qū)級的構(gòu)建配置如babel.config.json、CI 配置等放入所有任務(wù)的公共輸入任何一處變更都會正確觸發(fā)下游任務(wù)重跑。這種default / production / sharedGlobals的分層結(jié)構(gòu)正是避免輸出污染輸入、讓哈希計算既準(zhǔn)確又精簡的工程化實(shí)踐。檢查 3使用 Nx Cloud 調(diào)試工具對比兩次運(yùn)行前兩步確認(rèn)配置無誤后就可以借助 Nx Cloud 的對比工具來精確定位到底是哪個輸入變了。這是本課的核心實(shí)操環(huán)節(jié)完整步驟如下依據(jù) Troubleshoot Cache Misses確保倉庫已連接 Nx Cloud。若尚未連接可運(yùn)行npx nxlatest connect完成接入詳見 Remote caching 文檔。Nx Cloud 提供內(nèi)置的托管式遠(yuǎn)程緩存并支持通過訪問令牌Access Tokens精細(xì)控制 CI 對緩存的讀寫權(quán)限這正是課程第 8 課所講的內(nèi)容。點(diǎn)擊終端中打印的 run details 鏈接。每次運(yùn)行任務(wù)后Nx 都會在終端輸出一條指向該次運(yùn)行的鏈接打開后你可以按緩存狀態(tài)cache status搜索和過濾任務(wù)快速篩選出發(fā)生 cache miss 的那條任務(wù)。打開任務(wù)詳情面板點(diǎn)擊Compare to similar tasks按鈕。選擇要對比的基準(zhǔn)運(yùn)行從 Compared to 區(qū)域的相似任務(wù)列表中選擇一條或直接粘貼一條 run URL來與指定運(yùn)行對比。查看哈希輸入差異Nx Cloud 會對比兩條任務(wù)運(yùn)行的哈希輸入并高亮所有差異項使哪個輸入發(fā)生了變化一目了然。關(guān)鍵局限Nx Cloud 只能告訴你輸入不同不能告訴你源碼怎么不同官方文檔對此有一條重要說明見 Troubleshoot Cache MissesNx Cloud 無法訪問你的源代碼因此它只能基于已保存的內(nèi)容哈希告訴你哪些輸入不同而無法給出源碼的精確 git diff。這意味著排查思路應(yīng)是先用 Nx Cloud 鎖定是哪一組輸入哪個文件、哪類 glob、哪個環(huán)境變量發(fā)生變化再回到本地用git diff等工具確認(rèn)該輸入的具體改動內(nèi)容。兩者配合才能完成從輸入變了到為什么變了的完整定位。完整的排查路徑速查綜合本課內(nèi)容當(dāng)你在本地或 CI 中遇到任務(wù)本應(yīng)回放卻被重新執(zhí)行時可按以下順序自檢步驟檢查點(diǎn)驗(yàn)證方式1任務(wù)是否已開啟緩存nx show project project-name --web查看 Cacheable 標(biāo)簽確認(rèn)project.json或nx.json#targetDefaults中cache: true2任務(wù)的輸入與輸出是否配置正確核對inputs/namedInputs是否圈住了所有真正影響產(chǎn)物的文件確認(rèn)outputs覆蓋了所有產(chǎn)物目錄如.next用nx graph --fileoutput.json逐文件核對3哪組輸入發(fā)生了變化連接 Nx Cloud 后打開 run details 鏈接 → 按緩存狀態(tài)過濾 → 打開任務(wù)詳情 → Compare to similar tasks → 對比哈希輸入差異高亮處即根因所在深入學(xué)習(xí)倉庫中可繼續(xù)研讀的相關(guān)資料本文的權(quán)威排查原文Troubleshoot Cache Misses緩存系統(tǒng)概念與inputs/outputs精調(diào)Cache Task Results遠(yuǎn)程緩存的原理、安全與 CI 集成Remote caching本倉庫的namedInputs/targetDefaults完整配置范例nx.json課程配套的緩存配置課時03-configure-cache.md、08-remote-caching.md【免費(fèi)下載鏈接】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創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考