簡體   English   中英

Gitlab CI:npm 不喜歡緩存的 node_modules

[英]Gitlab CI: npm doesn't like the cached node_modules

互聯網上充斥着關於 Gitlab 不緩存的抱怨,但在我看來,Gitlab CI 確實緩存正確。 問題是,無論如何,npm 似乎都會再次安裝所有東西。

cache:
  key: ${CI_COMMIT_REF_SLUG}
  paths:
    - vendor/
    - bootstrap/
    - node_modules/

build-dependencies:
  image: ...
  stage: build
  script:
  - cp .env.gitlab-testing .env
  - composer install --no-progress --no-interaction
  - php artisan key:generate
  - npm install
  - npm run prod
  - npm run prod
  artifacts:
    paths:
    - vendor/
    - bootstrap/
    - node_modules/
    - .env
    - public/mix-manifest.json
  tags:
  - docker

這是我的 gitlab-ci.yml 文件(好吧..相關部分)。 雖然使用了緩存的 Composer 依賴項,但沒有使用 node_modules。 出於絕望,我什至將所有內容添加到緩存工件中。

實際上它應該可以工作,您的緩存是全局設置的,您的鍵是指當前分支${CI_COMMIT_REF_SLUG} ...

這是我的構建,它似乎在階段之間緩存 node_modules。

image: node:latest

cache:
  key: ${CI_COMMIT_REF_SLUG}
  paths:
  - node_modules/
  - .next/

stages:
  - install
  - test
  - build
  - deploy

install_dependencies:
  stage: install
  script:
    - npm install

test:
  stage: test
  script:
    - npm run test

build:
  stage: build
  script:
    - npm run build

我遇到了同樣的問題,對我來說問題出在緩存設置上,默認情況下緩存不保留未版本控制的 git 文件,並且由於我們不在 git 中存儲 node_modules,因此根本沒有緩存 npm 文件。 所以我所要做的就是插入一行“untracked: true”,如下所示

  cache:
  untracked: true
  key: ${CI_COMMIT_REF_SLUG}
  paths:
    - vendor/
    - bootstrap/
    - node_modules/

現在 npm 更快了,雖然它仍然需要檢查事情是否發生了變化,對我來說這仍然需要幾分鍾,所以我考慮讓一個特定的工作來執行 npm 安裝,但它已經加快了很多。

默認緩存路徑是~/.npm

設置 npm 緩存目錄:

npm config set cache <path> --global

請參閱此處了解更多信息

到目前為止我看到的所有答案只給出了一半的答案,但實際上並沒有完全完成緩存 IMO 的任務。

為了使用 npm & GitLab 進行完全緩存,您必須注意以下幾點:

  1. 在 CI/CD 環境中運行時,NPM 建議使用npm ci而不是npm install 僅供參考,這將需要package-lock.json的存在,它可以確保在 CI 環境中運行時不會自動更新任何包的版本(默認情況下npm i不會每次都創建相同的確定性構建,例如在工作中重新運行)。

  2. npm ci在重新安裝package-lock.json列出的所有包之前, node_modules先刪除了整個package-lock.json 因此,配置 GitLab 在構建作業之間緩存node_modules目錄是沒有用的。 關鍵是要確保沒有准備掛鈎或任何其他修改過的node_modules來自之前的運行。 IMO,這對於 CI 環境並不是真正有效,但您無法更改它並維護完全確定性的構建。

  3. NPM 有自己的緩存,它存儲在~/.npm/以備離線構建和整體速度。 您可以使用--cache <dir>選項指定不同的緩存位置(您將需要它)。 (@Amityo 答案的變化)

  4. GitLab無法緩存存儲庫之外的任何目錄! 這意味着無法緩存默認緩存目錄~/.npm

  5. 如果您有多個階段,則每個作業都會下載全局緩存。 這可能不是您想要的!

  6. 要在不重新運行安裝的情況下運行其他npx命令,您應該將node_modules/文件夾作為工件傳遞給其他作業。

我的解決方案

  • 在整個存儲庫中使用緩存的下載包(tar.gz)運行單個安裝作業作為.pre階段。
  • 僅在需要時將 node_modules 和構建目錄傳遞給其他作業

stages:
  - build
  - test
  - deploy

install:
  image: ...
  stage: .pre         # always first, no matter if it is listed in stages
  cache:
    key: NPM_DOWNLOAD_CACHE  # a single-key-4-all-branches for install jobs
    paths:
      - .npm/
  before_script:
    - cp .env.gitlab-testing .env
    - composer install --no-progress --no-interaction
    - php artisan key:generate
  script:
    # define cache dir & use it npm!
    - npm ci --cache .npm --prefer-offline
  artifacts:
    paths:
    - vendor/
    - bootstrap/
    - node_modules/
    - .env
    - public/mix-manifest.json

build:
  stage: build
  needs:
    - job: install         
      artifacts: true       # true by default, grabs `node_modules`
  script:
    - npm run build
  artifacts:
    paths:
      - dist/               # whereever your build results are stored

test:
  stage: test
  needs:
    - job: install
      artifacts: true      # grabs node_modules
    - job: build
      artifacts: true      # grabs built files
  script:
    - npm test

deploy:
  stage: deploy
  needs:
      # does not need node_modules so don't state install as a need
    - job: build
      artifacts: true      # grabs dist/
    - job: test            # must succeed
      artifacts: false     # not needed
  script:
    - npm publish

GitLab 對npm的推薦可以在GitLab Docs 中找到。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM