使用 github 操作缓存 npm 依赖项

Posted

技术标签:

【中文标题】使用 github 操作缓存 npm 依赖项【英文标题】:Caching npm dependency with github action 【发布时间】:2021-01-21 08:39:55 【问题描述】:

我想缓存 npm 依赖项,这样我就不会在每次推送时都执行 npm install 而只是从缓存中加载它。

我认为 github action 现在支持这个?:How do I cache steps in GitHub actions?

这里有几个案例

如果 package.json 发生变化,这意味着 yarn.lockpackage-lock.json 发生变化,因此请执行 npm 安装和更新缓存 扩展我的上述观点,贡献者可以同时做yarn installnpm install

从上述同一个问题,我将我的 github 操作更改为类似的内容

name: Tsc compilation test
on: [push, pull_request]
jobs:
  build:
    name: Build
    runs-on: ubuntu-18.04
    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Cache NPM dependencies
        uses: actions/cache@v1
        with:
          path: ~/.npm
          key: $ runner.OS -npm-cache-$ hashFiles('**/package-lock.json') 
          restore-keys: |
            $ runner.OS -npm-cache-
      - name: Install dependencies
        run: npm install
      - name: Test tsc
        run: npm run ts-compile-check

这仍然是 npm install 并且没有减少我安装依赖项的计算时间(所以我不确定这是否正常工作)

然后我做了yarn install axios,希望它会更新我的缓存,但在安装后我看到它已记录

Post job cleanup.
Cache hit occurred on the primary key Linux-npm-cache-, not saving cache.

所以这是我的问题,是否有可能实现

如果package.json 发生变化,这意味着yarn.lockpackage-lock.json 发生变化,npm install 也会发生变化并更新缓存 扩展我的上述观点,贡献者可以同时做yarn installnpm install

有人可以解释一下吗

    with:
      path: ~/.npm
      key: $ runner.OS -npm-cache-$ hashFiles('**/package-lock.json') 
      restore-keys: |
        $ runner.OS -npm-cache-

【问题讨论】:

像github.com/actions/cache 这样的操作会更好吗?或者像github.com/tinovyatkin/alphabank-pay-node/blob/… 这样的另一个例子会显示出让您的案例更好地工作的差异吗? 有关密钥的详细信息,另请参阅github.com/ktmud/cached-dependencies#cache-configs。 您的 package-lock.json 是否已在您的仓库中签入?否则,缓存键将无法正确计算,因为锁定文件仅在下一步生成。 【参考方案1】:

为了使用 GitHub 操作进行高效缓存,需要存在 package-lock.jsonyarn.lock。该文件是在安装包时自动生成的。如果您想了解有关 package-lock.json 的更多信息,请check out the docs。

现在的话题是 npm 和 yarn 是否应该在同一个项目中使用。 More about that subject here.

基于这个问题,我们假设 package-lock.json 和 yarn.lock 都存在。如果您只使用两者之一,请随意从下面删除一个。下面的配置适用于纱线版本 2,它使用 yarn config get cacheFolder 来获取缓存文件夹。对于另一个纱线版本see the docs。

name: Tsc compilation test
on: [push, pull_request]
jobs:
  build:
    name: Build
    runs-on: ubuntu-18.04
    steps:
      - name: Checkout
        uses: actions/checkout@v2

      - name: Get yarn cache directory path
        id: yarn-cache-dir-path
        run: echo "::set-output name=dir::$(yarn config get cacheFolder)"

      - name: Cache yarn dependencies
        uses: actions/cache@v2
        with:
          path: $ steps.yarn-cache-dir-path.outputs.dir 
          key: $ runner.os -yarn-$ hashFiles('**/yarn.lock') 
          restore-keys: |
            $ runner.os -yarn-

      - name: Cache npm dependencies
        uses: actions/cache@v2
        with:
          path: '~/.npm'
          key: $ runner.os -node-$ hashFiles('**/package-lock.json') 
          restore-keys: |
            $ runner.os -node-

      - name: Install dependencies
        run: npm install # or yarn install

      - name: Test tsc
        run: npm run ts-compile-check

就是这样!好吧,除了一件事。上面我们使用~/.npm 来缓存 npm 依赖项。在性能方面,缓存**/node_modules 会更快,但是在某些情况下这会引入冲突。随意尝试,看看哪一个适合你。更多关于 here 和 here 的信息。


根据您的问题,您还要求解释以下代码:

    with:
      path: ~/.npm
      key: $ runner.OS -npm-cache-$ hashFiles('**/package-lock.json') 
      restore-keys: |
        $ runner.OS -npm-cache-

https://github.com/actions/cache#usage:

路径 - 要缓存和恢复的文件、目录和通配符模式的列表。请参阅@actions/glob 了解支持的模式。key - 用于恢复和保存缓存的显式键restore-keys - 键的有序列表如果 key 没有发生缓存命中,则用于恢复缓存

因此上面的代码:

path 是将被缓存/恢复的文件夹(安装依赖项的位置) key 是要缓存的路径的唯一标识符。在这种情况下,它使用hashFiles 散列任何**/package-lock.json 文件的内容。基本上当 package-lock.json 文件发生变化时,这意味着依赖项发生了变化,不应该使用缓存。 restore-keys 基本上是一个默认键,以防key 不匹配

【讨论】:

这个动作会缓存 npm deps,但不会跳过npm install。为此,您需要在缓存步骤中添加一个 id,例如 id: cache-npm-deps,然后将 if: steps.cache-npm-deps.outputs.cache-hit != 'true' 添加到您的安装依赖项步骤中。

以上是关于使用 github 操作缓存 npm 依赖项的主要内容,如果未能解决你的问题,请参考以下文章

在 Windows 上的 GitHub Actions 中缓存依赖项

在 circleci 中缓存 npm 依赖项

NPM 仅安装后依赖项

在 Heroku 上使用带有 npm 和 Node 的 Git 依赖项

在 github repo 上使用 NPM 安装 React 依赖项

无法从 GitHub NPM 注册表 (npm.pkg.github.com) 通过 yarn 下载依赖项