6月4日 23:10
How do you use npm effectively in CI/CD pipelines and what are the best practices?
Using npm in CI/CD environments is crucial for automated building, testing, and deployment. Understanding best practices can significantly improve the efficiency and reliability of CI/CD workflows.
npm Best Practices in CI/CD Environments
1. Use npm ci Instead of npm install
npm ci is specifically designed for CI environments and is faster and more reliable than npm install.
bash# Use npm ci in CI environment npm ci
Advantages:
- Uses package-lock.json directly, skipping some user-level configurations
- Deletes node_modules and reinstalls, ensuring a clean environment
- Faster installation speed
- Better reproducibility
Comparison:
| Feature | npm install | npm ci |
|---|---|---|
| Speed | Slower | Faster |
| Reproducibility | Lower | Higher |
| Use Case | Development environment | CI/CD environment |
| package-lock.json | Optional | Required |
2. Cache Dependencies
Caching dependencies can significantly reduce CI/CD build time.
GitHub Actions Example
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 Example
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 Example
groovypipeline { agent any stages { stage('Install') { steps { sh 'npm ci' } } stage('Test') { steps { sh 'npm test' } } stage('Build') { steps { sh 'npm run build' } } } }
3. Parallelize Tasks
Running tasks in parallel can reduce overall build time.
yaml# GitHub Actions - Run tests in parallel 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. Security Audit
Integrate security audits in CI/CD to detect vulnerabilities early.
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. Dependency Update Check
Regularly check for dependency updates to keep the project up-to-date.
yaml- name: Check for outdated packages run: npm outdated - name: Update dependencies run: npm update if: github.event_name == 'schedule'
Configuration for Different CI/CD Platforms
GitHub Actions
Basic Configuration
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/
Publish to 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
Basic Configuration
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/
Publish to npm
yamlpublish: stage: deploy only: - tags script: - npm ci - npm publish variables: NPM_TOKEN: ${CI_JOB_TOKEN}
CircleCI
Basic Configuration
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
Basic Configuration
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' } } } }
Performance Optimization
1. Use Caching
yaml# GitHub Actions - uses: actions/cache@v3 with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} restore-keys: | ${{ runner.os }}-node-
2. Parallel Installation
bash# Set parallelism npm config set maxsockets 50 npm config set network-concurrency 16
3. Use Mirrors
bash# Use domestic mirror npm config set registry https://registry.npmmirror.com
4. Reduce Dependencies
bash# Install only production dependencies npm ci --production # Use npm prune to remove unnecessary dependencies npm prune --production
Security Best Practices
1. Use Environment Variables
yaml# GitHub Actions env: NPM_TOKEN: ${{ secrets.NPM_TOKEN }} NODE_ENV: production
2. Regular Audits
yaml- name: Security audit run: | npm audit npm audit fix
3. Use .npmignore
shell# .npmignore .env *.key *.pem secrets/
4. Lock Dependency Versions
json{ "dependencies": { "package": "1.2.3" } }
Common Issues
1. Installation Failure
yaml- name: Install dependencies run: | npm ci || npm install --force
2. Cache Issues
yaml- name: Clear cache run: npm cache clean --force
3. Permission Issues
yaml- name: Fix permissions run: | npm config set user 0 npm config set group 0
Monitoring and Reporting
1. Test Coverage
yaml- name: Generate coverage run: npm run test:coverage - name: Upload coverage uses: codecov/codecov-action@v3
2. Build Report
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. Dependency Report
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
Mastering npm best practices in CI/CD can significantly improve build efficiency, ensure code quality, and enhance security.