npm 在 CI/CD 环境中的使用对于自动化构建、测试和部署至关重要。了解最佳实践可以显著提高 CI/CD 流程的效率和可靠性。
CI/CD 环境中的 npm 最佳实践
1. 使用 npm ci 替代 npm install
npm ci 专门为 CI 环境设计,比 npm install 更快、更可靠。
bash# CI 环境中使用 npm ci npm ci
优势:
- 直接使用 package-lock.json,跳过某些用户级配置
- 删除 node_modules 后重新安装,确保干净的环境
- 更快的安装速度
- 更好的可重现性
对比:
| 特性 | npm install | npm ci |
|---|---|---|
| 速度 | 较慢 | 更快 |
| 可重现性 | 较低 | 更高 |
| 使用场景 | 开发环境 | CI/CD 环境 |
| package-lock.json | 可选 | 必需 |
2. 缓存依赖
缓存依赖可以显著减少 CI/CD 构建时间。
GitHub Actions 示例
yamlname: Build and Test on: push: branches: [main] pull_request: branches: [main] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Setup Node.js uses: actions/setup-node@v3 with: node-version: '18' cache: 'npm' - name: Install dependencies run: npm ci - name: Run tests run: npm test - name: Build run: npm run build
GitLab CI 示例
yamlimage: node:18 cache: key: ${CI_COMMIT_REF_SLUG} paths: - node_modules/ stages: - install - test - build install: stage: install script: - npm ci test: stage: test script: - npm test build: stage: build script: - npm run build
Jenkins Pipeline 示例
groovypipeline { agent any stages { stage('Install') { steps { sh 'npm ci' } } stage('Test') { steps { sh 'npm test' } } stage('Build') { steps { sh 'npm run build' } } } }
3. 并行化任务
并行运行任务可以减少总体构建时间。
yaml# GitHub Actions - 并行运行测试 jobs: test: strategy: matrix: node-version: [14, 16, 18] runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: node-version: ${{ matrix.node-version }} cache: 'npm' - run: npm ci - run: npm test
4. 安全审计
在 CI/CD 中集成安全审计,及时发现漏洞。
yaml- name: Run security audit run: npm audit - name: Attempt to fix vulnerabilities run: npm audit fix continue-on-error: true - name: Check for critical vulnerabilities run: | if [ $(npm audit --json | jq '.metadata.vulnerabilities.critical') -gt 0 ]; then echo "Critical vulnerabilities found!" exit 1 fi
5. 依赖更新检查
定期检查依赖更新,保持项目最新。
yaml- name: Check for outdated packages run: npm outdated - name: Update dependencies run: npm update if: github.event_name == 'schedule'
不同 CI/CD 平台的配置
GitHub Actions
基本配置
yamlname: CI on: push: branches: [main, develop] pull_request: branches: [main] jobs: build: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v3 - name: Setup Node.js uses: actions/setup-node@v3 with: node-version: '18' cache: 'npm' - name: Install dependencies run: npm ci - name: Run linter run: npm run lint - name: Run tests run: npm test - name: Build run: npm run build - name: Upload artifacts uses: actions/upload-artifact@v3 with: name: dist path: dist/
发布到 npm
yamlname: Publish to npm on: push: tags: - 'v*' jobs: publish: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: node-version: '18' registry-url: 'https://registry.npmjs.org' - run: npm ci - run: npm test - run: npm publish env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
GitLab CI
基本配置
yamlstages: - install - test - build - deploy variables: NODE_ENV: test cache: key: ${CI_COMMIT_REF_SLUG} paths: - node_modules/ install: stage: install script: - npm ci artifacts: paths: - node_modules/ test: stage: test dependencies: - install script: - npm test coverage: '/All files[^|]*\|[^|]*\|[^|]*\s([\d\.]+)/' build: stage: build dependencies: - install script: - npm run build artifacts: paths: - dist/
发布到 npm
yamlpublish: stage: deploy only: - tags script: - npm ci - npm publish variables: NPM_TOKEN: ${CI_JOB_TOKEN}
CircleCI
基本配置
yamlversion: 2.1 orbs: node: circleci/node@5.0.0 jobs: build-and-test: docker: - image: cimg/node:18.0.0 steps: - checkout - node/install-packages - run: name: Run tests command: npm test - run: name: Build command: npm run build - persist_to_workspace: root: . paths: - dist workflows: build-test-deploy: jobs: - build-and-test
Jenkins
基本配置
groovypipeline { agent any environment { NODE_ENV = 'test' } stages { stage('Install') { steps { sh 'npm ci' } } stage('Test') { steps { sh 'npm test' } } stage('Build') { steps { sh 'npm run build' } } stage('Deploy') { when { tag pattern: "v\\d+\\.\\d+\\.\\d+", comparator: "REGEXP" } steps { sh 'npm publish' } } } }
性能优化
1. 使用缓存
yaml# GitHub Actions - uses: actions/cache@v3 with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} restore-keys: | ${{ runner.os }}-node-
2. 并行安装
bash# 设置并行度 npm config set maxsockets 50 npm config set network-concurrency 16
3. 使用镜像
bash# 使用国内镜像 npm config set registry https://registry.npmmirror.com
4. 减少依赖
bash# 只安装生产依赖 npm ci --production # 使用 npm prune 移除不需要的依赖 npm prune --production
安全最佳实践
1. 使用环境变量
yaml# GitHub Actions env: NPM_TOKEN: ${{ secrets.NPM_TOKEN }} NODE_ENV: production
2. 定期审计
yaml- name: Security audit run: | npm audit npm audit fix
3. 使用 .npmignore
shell# .npmignore .env *.key *.pem secrets/
4. 锁定依赖版本
json{ "dependencies": { "package": "1.2.3" } }
常见问题
1. 安装失败
yaml- name: Install dependencies run: | npm ci || npm install --force
2. 缓存问题
yaml- name: Clear cache run: npm cache clean --force
3. 权限问题
yaml- name: Fix permissions run: | npm config set user 0 npm config set group 0
监控和报告
1. 测试覆盖率
yaml- name: Generate coverage run: npm run test:coverage - name: Upload coverage uses: codecov/codecov-action@v3
2. 构建报告
yaml- name: Build report run: npm run build -- --report - name: Upload report uses: actions/upload-artifact@v3 with: name: build-report path: build-report.json
3. 依赖报告
yaml- name: Dependency report run: | npm ls --json > dependencies.json npm outdated --json > outdated.json - name: Upload reports uses: actions/upload-artifact@v3 with: name: dependency-reports path: | dependencies.json outdated.json
掌握 npm 在 CI/CD 中的最佳实践可以显著提高构建效率、确保代码质量和安全性。