Azure DevOps中的NPM Cache步骤无法正常工作

12
我按照 Microsoft 文档 https://learn.microsoft.com/en-us/azure/devops/pipelines/release/caching?view=azure-devops#nodejsnpm 配置了 npm 缓存步骤,用于在 Azure 中构建 Android 应用程序。与 package.json-Lock 不同,我使用的是 package.json。在第二次运行管道时,我能够在 post-cache 步骤中上传缓存依赖文件并正确地在开头上传该文件,但即使 npm 缓存数据已经下载到工作区,npm install 步骤仍然调用远程库并下载远程依赖项。我还尝试了在 npm install 步骤中运行 npm install --prefer-offline,但没有奏效。请让我知道是否有其他遗漏的地方,谢谢。
3个回答

13

使用Cache任务来缓存应用程序的node_modules文件夹。使用缓存命中变量(cacheHitVar)来存储缓存恢复的结果。当缓存被恢复(缓存命中)时,它将被设置为true,否则设置为false

然后为安装依赖项的任务(例如npm ci)使用条件。只在缓存未命中时安装它们。

steps:
  - task: Cache@2
    displayName: Cache node_modules
    inputs:
      key: 'npm | "$(Agent.OS)" | $(Build.SourcesDirectory)/package-lock.json'
      path: $(Build.SourcesDirectory)/node_modules
      cacheHitVar: CACHE_RESTORED

  - task: Npm@1
    displayName: 'Install the dependencies'
    inputs:
      command: custom
      verbose: false
      customCommand: 'ci'
    condition: ne(variables.CACHE_RESTORED, 'true')
当缓存成功恢复时,管道执行将显示以下输出。

Azure Pipeline Execution


这需要将 package-lock.json 添加到 git 中(不被忽略)吗? - JBS
1
@JBS 是的,因为缓存键部分基于锁定文件,并且使用了 npm ci 命令,该命令需要锁定文件。尽管存在这个问题,我仍建议将锁定文件添加到您的 Git 存储库中。这样,当其他开发人员在本地克隆存储库时,他们将安装相同版本的依赖项。以避免出现“在我的机器上可以运行”的问题。您不希望直接或间接的依赖项在您不知情的情况下被更新。 - Christophe Geers
1
感谢@Christophe。我尝试了这种方法,但在我的情况下,缓存方法实际上花费了更长的时间 - 下载存储的缓存需要很长时间,可能是由于构建服务器的连接和性能限制(未使用基于云的代理)。在我的情况下,最快的方法是使用npm install --prefer-offline --no-audit - JBS
我在Azure DevOps上也有类似的经历。尽管缓存可以节省时间,但最终并不值得。由于网络延迟,有时它会变得更慢。如果您拥有一个带有数据使用限制的私有软件包注册表,那将会很有帮助。 - Christophe Geers
@ChristopheGeers - 你觉得使用你发布的条件缓存更好还是customCommand: 'ci --cache $(npm_config_cache)'?选择方案的优缺点有哪些? - BadNews
显示剩余4条评论

5
请查看微软公司关于节点模块缓存的官方建议,详情请点击https://learn.microsoft.com/zh-cn/azure/devops/pipelines/release/caching?view=azure-devops#nodejsnpm
variables:
  npm_config_cache: $(Pipeline.Workspace)/.npm

steps:
- task: Cache@2
  inputs:
    key: 'npm | "$(Agent.OS)" | package-lock.json'
    restoreKeys: |
       npm | "$(Agent.OS)"
    path: $(npm_config_cache)
  displayName: Cache npm

- script: npm ci


由于npm ci会删除node_modules文件夹,以确保使用一致且可重复的模块集,因此在调用npm ci时应避免缓存node_modules

1

这并不是一个很好的答案,因为我也有完全相同的问题,但是这是我的设置。

- task: Cache@2
  displayName: Cache npm
  inputs:
    key: 'npm | "$(Agent.OS)" | $(Build.SourcesDirectory)/XX/package-lock.json'
    restoreKeys: |
       npm | "$(Agent.OS)"
    path: $(npm_config_cache)

- task: Npm@1
  displayName: Npm restore dependencies
  inputs:
    command: 'custom'
    workingDir: '$(clientapps)'
    customCommand: 'install --cache $(npm_config_cache)'

添加--cache会将npm的缓存文件设置为特定位置。我现在正在使用--prefer-offline运行构建,看看是否有帮助。如果有帮助,我会在这里回答。


这有帮助吗?与此相关的答案似乎各不相同。 - Jacob Morrison
我已经在我的管道中使用了--prefer-offline进行设置,但似乎并没有什么作用——尽管这也可能是因为我的package-lock.json在运行之间发生了变化。我的管道不经常运行... 无论如何,在我的端上构建仍然比恢复依赖项要花费更长的时间,所以我停止了研究。你可以尝试的是,如果从缓存中恢复成功,则不运行npm restore(缓存任务可以输出一个布尔值,请查看Azure管道文档)-但我不知道那是否有效。 - sommmen
我作为测试再次运行了管道,但似乎它仍然无法正常工作:##[warning]The given cache key has changed in its resolved value between restore and save steps; 因此锁定文件被更改了?无论如何 - 我做错了什么,但我现在不会进一步调查。 - sommmen
啊 - 这是因为我正在使用 npm install,它会重写文件,我应该使用 npm ci,但那会导致错误,所以我不能使用它。因此,目前对我来说似乎无法进行缓存。 - sommmen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接