如何优化Gitlab CI中存在大体积npm依赖时的工作流程?
GitLab CI 大体积npm依赖(以Puppeteer为例)优化方案
完全可以通过预安装的方式实现你要的效果,以下是两种落地性最高的方案:
方案1:使用预装Puppeteer的自定义Runner镜像
该方案完全符合你的需求,无需每次缓存上下传Puppeteer包,也不用在npm install时重复安装该依赖,适合Puppeteer版本更新频率较低的项目。
实现步骤:
- 基于你流水线常用的Node基础镜像(如
node:20-bullseye)构建自定义镜像,提前安装好对应版本的Puppeteer及Chrome浏览器,同时配置好相关环境变量 - 将构建完成的镜像推送到公司私有镜像仓库,CI任务直接指定该镜像作为运行环境
- 项目
package.json中保留Puppeteer的依赖声明,执行npm install前设置PUPPETEER_SKIP_DOWNLOAD=true,只会安装其他小体积依赖,不会重复下载Chrome二进制包
自定义镜像Dockerfile示例
FROM node:20-bullseye # 安装Chrome运行所需的系统依赖库 RUN apt-get update && apt-get install -y \ ca-certificates \ fonts-liberation \ libasound2 \ libatk-bridge2.0-0 \ libatk1.0-0 \ libc6 \ libcairo2 \ libcups2 \ libdbus-1-3 \ libexpat1 \ libfontconfig1 \ libgbm1 \ libgcc1 \ libglib2.0-0 \ libgtk-3-0 \ libnspr4 \ libnss3 \ libpango-1.0-0 \ libpangocairo-1.0-0 \ libstdc++6 \ libx11-6 \ libx11-xcb1 \ libxcb1 \ libxcomposite1 \ libxcursor1 \ libxdamage1 \ libxext6 \ libxfixes3 \ libxi6 \ libxrandr2 \ libxrender1 \ libxss1 \ libxtst6 \ lsb-release \ wget \ xdg-utils \ --no-install-recommends \ && rm -rf /var/lib/apt/lists/* # 全局安装和项目版本一致的Puppeteer,提前下载Chrome RUN npm install -g puppeteer@21.5.0 # 配置环境变量,项目安装时跳过Chrome下载 ENV PUPPETEER_SKIP_DOWNLOAD=true # 配置Node全局依赖路径,让项目能识别全局安装的Puppeteer ENV NODE_PATH=/usr/local/lib/node_modules
.gitlab-ci.yml 示例配置
frontend-test: image: your-private-registry/puppeteer-node:20 # 替换为你构建的自定义镜像地址 script: - npm install # 仅安装除Puppeteer外的其他项目依赖,耗时极短 - npm run test # 执行你的业务脚本,可正常调用Puppeteer
方案2:拆分缓存策略,单独隔离Puppeteer缓存
如果你暂时不想维护自定义镜像,可以用该方案减少缓存上下传体积,适合Puppeteer版本更新频繁的项目。
实现逻辑是将Puppeteer的缓存和其他依赖缓存拆分,Puppeteer缓存仅在版本变更时才会更新,平时不会重复上传下载:
variables: # 自定义Puppeteer缓存目录 PUPPETEER_CACHE_DIR: $CI_PROJECT_DIR/.puppeteer_cache cache: # 缓存除Puppeteer外的其他依赖 - key: files: - package-lock.json paths: - node_modules/ policy: pull-push exclude: - node_modules/puppeteer/**/* # 单独缓存Puppeteer,仅版本变化时才更新 - key: files: - package-lock.json prefix: puppeteer-cache-v1 paths: - $PUPPETEER_CACHE_DIR policy: pull-push frontend-test: script: - npm install - npm run test
注意事项
- 自定义镜像中的Puppeteer版本必须和项目
package.json中声明的版本完全一致,避免API不兼容问题 - 如果使用alpine系基础镜像,不要使用Puppeteer默认下载的Chrome,需单独安装alpine源中的Chromium,否则会出现glibc兼容问题
- 使用全局安装的Puppeteer时要确保
NODE_PATH环境变量配置正确,否则项目会出现找不到依赖的报错
内容的提问来源于stack exchange,提问作者Lehks
相关产品推荐
相关产品推荐

