How to setup npm caching on GitLab

Marcin Wosinek - Jul 29 '21 - - Dev Community

In this article, I'll show how to set up & use npm caching in GitLab CI.

Example package

For this article, I created a project with create-react-app. It's installing quite a few dependencies, and we need enough of them to see the positive impact of caching on the run time.

Baseline

The baseline CI configuration is as follow:

image: node:16

stages:
  - build

build:
  stage: build
  script:
    - npm ci
Enter fullscreen mode Exit fullscreen mode

To simplify, I only run the installation with npm ci. In this way, the complete time of the job is setting up the stage for the build itself - getting the node:16 image to the agent & dependencies for npm.

I run the build with this configuration 3 times, and every time the total time was 1 minute 41 seconds in our baseline.

Adding cache

For enabling the cache, the configuration gets a bit more complicated

image: node:16

stages:
  - build

cache:
  key: npm
  policy: pull-push
  paths:
    - .npm/

build:
  stage: build
  script:
    - npm ci --cache .npm --prefer-offline
Enter fullscreen mode Exit fullscreen mode

Where:

  • cache:key: npm - I want to share this cache across different CI runs. In the documentation they show an example of how to limit cache use only to the current CI run - in the case of npm dependencies, they are safe to reuse between CI runs, especially because npm still will make sure to install them in the correct version.
  • policy: pull-push - setting the default cache policy explicitly - it will load the cache before & upload it after the job run. If we were adding more jobs, we could save few seconds making sure we only pull-push from the very first one, and all the others will only pull
  • paths: .npm/ - a folder we picked for keeping the cache. If you use git during your builds (to create commits, or to run git describe), it would make sense to add it to your .gitingore
  • npm ci --cache .npm --prefer-offline - first we tell npm where to find the cache with --cache .npm, second --prefer-offline disables online checks of cached packages.

Cold cache

The first run after setting up the cache took 1 minute 48 seconds. The 7s we lost in comparison to baseline is downloading & uploading the cache files.

Warm cache

I run the job 3 times & always got not more than 1 minute 6 seconds.
So we saved 35s of the installation in this simple use case - in cases of more complex apps, the time saved will get even better.

Links

You can find the complete repository here.

Summary

In this article, we have seen how to speed up the npm installation in the GitLab CI. The half a minute gain we had here, in a real-world case, will most likely appear in a few places on the critical path of our CI run.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .