解决Azure Pipeline中Cache@2存储NX缓存(无NX Cloud)的key失效问题
问题
使用Nx管理单体仓库,未使用NX Cloud,计划通过Azure Pipeline的Cache@2任务缓存Nx构建结果以优化构建时间。已了解Nx本地缓存机制,但当前配置的Cache@2任务仅以nx.json作为缓存指纹,导致源码变更时仍复用旧缓存,仅nx.json更新才会更新缓存。需要正确的Cache@2配置(含缓存key、路径定义)及必要的Nx缓存设置步骤。当前pipeline.yml配置如下:
steps: - task: NodeTool@0 inputs: versionSpec: '20.17.x' displayName: 'Install Node.js' - task: Cache@2 inputs: key: 'npm | "$(Agent.OS)" | $(projectPath)/package-lock.json' path: '$(NODE_MODULES_CACHE_FOLDER)' cacheHitVar: NODE_MODULES_CACHE_RESTORED workingDirectory: '$(projectPath)' displayName: 'Restore node_modules cache' - task: Cache@2 inputs: key: 'nx | "$(Agent.OS)" | $(projectPath)/nx.json' path: '$(NX_CACHE_FOLDER)' cacheHitVar: NX_CACHE_RESTORED workingDirectory: '$(projectPath)' displayName: 'Restore NX cache'
解决方案
一、Nx本地缓存基础配置
先确保Nx本地缓存已启用,检查nx.json中的配置:
{ "tasksRunnerOptions": { "default": { "runner": "nx/tasks-runners/default", "options": { "cacheableOperations": ["build", "test", "lint"], // 按需添加需要缓存的操作 "cacheDirectory": ".nx/cache" // 本地缓存存储路径,默认值,可自定义 } } } }
cacheableOperations:指定需要缓存的任务类型,比如build、test、lint等,根据项目需求调整。cacheDirectory:缓存文件的存储路径,后续Azure Pipeline的Cache任务将针对该目录做缓存。
二、Azure Pipeline Cache@2核心配置优化
问题根源是缓存key仅依赖nx.json,无法感知源码变更。我们可以通过生成Nx项目变更哈希文件,将其加入缓存key,确保源码、依赖或配置变更时触发缓存更新。
1. 生成Nx变更哈希文件
在Pipeline中添加步骤,生成反映代码变更的哈希文件:
- script: npx nx print-affected --base=HEAD~1 --head=HEAD --plain > nx-affected-hash.txt workingDirectory: '$(projectPath)' displayName: 'Generate Nx affected hash'
该命令对比当前提交与上一次提交的变更,生成受影响任务的哈希信息并写入nx-affected-hash.txt,作为缓存key的核心指纹。
2. 调整Nx缓存的Cache@2任务
更新Cache@2的key,合并操作系统、nx.json配置和变更哈希文件:
- task: Cache@2 inputs: key: 'nx | "$(Agent.OS)" | $(projectPath)/nx.json | $(projectPath)/nx-affected-hash.txt' path: '$(projectPath)/.nx/cache' # 对应nx.json中配置的cacheDirectory cacheHitVar: NX_CACHE_RESTORED workingDirectory: '$(projectPath)' displayName: 'Restore and save NX cache'
- key:多维度指纹确保任何影响构建的变更都会生成新缓存key。
- path:直接指向Nx本地缓存目录,避免变量配置错误。
3. node_modules缓存优化(可选)
原node_modules缓存配置可保留,也可加入package.json增强指纹准确性:
- task: Cache@2 inputs: key: 'npm | "$(Agent.OS)" | $(projectPath)/package.json | $(projectPath)/package-lock.json' path: '$(projectPath)/node_modules' cacheHitVar: NODE_MODULES_CACHE_RESTORED workingDirectory: '$(projectPath)' displayName: 'Restore node_modules cache'
三、完整Pipeline示例
steps: - task: NodeTool@0 inputs: versionSpec: '20.17.x' displayName: 'Install Node.js' # 缓存node_modules - task: Cache@2 inputs: key: 'npm | "$(Agent.OS)" | $(projectPath)/package.json | $(projectPath)/package-lock.json' path: '$(projectPath)/node_modules' cacheHitVar: NODE_MODULES_CACHE_RESTORED workingDirectory: '$(projectPath)' displayName: 'Restore node_modules cache' # 仅缓存未命中时安装依赖 - script: npm ci workingDirectory: '$(projectPath)' displayName: 'Install dependencies' condition: ne(variables.NODE_MODULES_CACHE_RESTORED, 'true') # 生成Nx变更哈希文件 - script: npx nx print-affected --base=HEAD~1 --head=HEAD --plain > nx-affected-hash.txt workingDirectory: '$(projectPath)' displayName: 'Generate Nx affected hash' # 缓存Nx构建结果 - task: Cache@2 inputs: key: 'nx | "$(Agent.OS)" | $(projectPath)/nx.json | $(projectPath)/nx-affected-hash.txt' path: '$(projectPath)/.nx/cache' cacheHitVar: NX_CACHE_RESTORED workingDirectory: '$(projectPath)' displayName: 'Restore and save NX cache' # 执行Nx构建任务 - script: npx nx build <your-project-name> workingDirectory: '$(projectPath)' displayName: 'Run Nx build'
四、验证缓存有效性
- 查看Pipeline中Cache@2任务的日志,确认缓存命中状态。
- 修改源码后重新运行Pipeline,此时
nx-affected-hash.txt内容变化,缓存key更新,将生成新缓存而非复用旧缓存。 - 可通过
npx nx show cache命令查看本地缓存内容,验证缓存存储是否正确。
内容的提问来源于stack exchange,提问作者Prabhas Kumra
相关产品推荐
相关产品推荐

