Cache NPM dependencies on Jenkins pipeline Cache NPM dependencies on Jenkins pipeline jenkins jenkins

Cache NPM dependencies on Jenkins pipeline


What I have done in my Jenkins pipeline for 3 different projects is using tar instead of cp and then npm install instead of npm ci, for each:

  1. cd to your project
  2. npm i
  3. tar cvfz ${HOME}/your_project_node_modules.tar.gz node_modules

Then in the pipeline:

dir(your_project){  sh "tar xf ${HOME}/your_project_node_modules.tar.gz"  sh "npm i"}

Of course it has the disadvantage that with time dependencies change and the install will take longer, but I've managed to reduce my disk space usage in the image by about 0.5GB and tar is much faster then cp (cp ~30 sec, tar ~5 sec)

Total install time went in my case from about 3 minutes to a matter of seconds.


NPM has a global cache stored in ~/.npm


Those parts of the Jenkinsfile will do the following:

On Branch master and develop, a fresh npm install is always executed.

On all other branches, the package.json will be md5 hashed and after the npm install the node_modules folder will be placed in the defined cache folder like:<CACHE_DIRECTORY>/<MD5_SUM_PACKAGE_JSON>/node_modules.

The next build can reuse the node_modules and doesn't have to download all the node_modules again.

parameters {    booleanParam(name: "CACHED_NODE_MODULES",            description: "Should node_modules be taken from cache?",            defaultValue: !'master'.equals(env.BRANCH_NAME) && !'develop'.equals(env.BRANCH_NAME))}

...

stage('Build') {   steps {      cacheOrRestoreNodeModules()      echo "Performing npm build..."      sh 'npm install'   }}

...

def cacheOrRestoreNodeModules() {if (params.CACHED_NODE_MODULES) {    sh '''    MD5_SUM_PACKAGE_JSON=($(md5sum package.json))    CACHE_FOLDER=/home/jenkins/.cache/npm/${MD5_SUM_PACKAGE_JSON}        # check if folder exists and copy node_modules to current directory    if [ -d ${CACHE_FOLDER} ]; then      cp -r ${CACHE_FOLDER}/node_modules .    fi        npm install --no-audit        # if folder does not exists, create it and cache node_modules folder    if ! [ -d ${CACHE_FOLDER} ]; then      mkdir -p ${CACHE_FOLDER}      cp -r node_modules ${CACHE_FOLDER}/node_modules    fi    '''}

}