devops2025-04-28·8 min·106/348

Vercel 배포 스크립트 커스터마이징

Vercel 배포 프로세스를 커스터마이징하여 빌드 시간을 줄이고 배포 워크플로우를 최적화하는 방법을 알아봅니다.

Vercel 배포 스크립트 커스터마이징

Introduction

Vercel은 Next.js 프로젝트의 배포를 자동화하는 데 탁월한 플랫폼입니다. 하지만 기본 배포 설정만으로는 복잡한 프로젝트의 요구사항을 충족하기 어려울 때가 많습니다. 이 글에서는 Vercel 배포 스크립트를 커스터마이징하여 빌드 시간을 줄이고, 에러 핸들링을 강화하며, 배포 워크플로우를 최적화하는 방법을 살펴보겠습니다.

Environment

  • Vercel 프로젝트 (Next.js 14+)
  • Node.js 18+
  • Vercel CLI 30+
  • monorepo 환경 (Turborepo)

Problem

기본 Vercel 배포 설정은 단순한 프로젝트에는 적합하지만, monorepo 구조나 복잡한 빌드 프로세스를 가진 프로젝트에서는 문제가 발생할 수 있습니다:

  1. 불필요한 패키지까지 빌드되어 빌드 시간이 증가
  2. 빌드 에러 발생 시 적절한 로깅이 없음
  3. 배포 전 검증 단계 부재
  4. 환경 변수 검증 미흡

Analysis

Vercel의 배포 프로세스는 vercel.json 설정과 package.json의 빌드 스크립트를 기반으로 동작합니다. 기본적으로 Vercel은 npm run build를 호출하고, 그 결과물을 서버리스 함수로 배포합니다.

커스터마이징 포인트:

  • buildCommand: 빌드 명령어 커스터마이징
  • installCommand: 의존성 설치 명령어
  • outputDirectory: 빌드 출력 디렉토리
  • framework: 프레임워크 설정

Solution

1. 빌드 스크립트 커스터마이징

package.json에 빌드 스크립트를 추가합니다:

{
  "scripts": {
    "vercel-build": "turborepo build --filter=@myapp/web...",
    "vercel-postbuild": "node scripts/post-build.js"
  }
}

2. vercel.json 설정

{
  "buildCommand": "npm run vercel-build",
  "installCommand": "npm install --frozen-lockfile",
  "outputDirectory": ".next",
  "framework": "nextjs",
  "regions": ["iad1"],
  "functions": {
    "app/api/**/*.js": {
      "maxDuration": 30
    }
  }
}

3. 빌드 전 검증 스크립트

// scripts/pre-build.js
const { execSync } = require('child_process');

function validateEnvironment() {
  const required = ['DATABASE_URL', 'API_KEY', 'NEXTAUTH_SECRET'];
  const missing = required.filter(key => !process.env[key]);
  
  if (missing.length > 0) {
    console.error('Missing environment variables:', missing);
    process.exit(1);
  }
}

function runTests() {
  try {
    execSync('npm run test:unit', { stdio: 'inherit' });
    execSync('npm run lint', { stdio: 'inherit' });
  } catch (error) {
    console.error('Pre-build checks failed');
    process.exit(1);
  }
}

validateEnvironment();
runTests();
console.log('Pre-build checks passed');

4. 빌드 후 처리 스크립트

// scripts/post-build.js
const fs = require('fs');
const path = require('path');

function analyzeBundle() {
  const buildDir = path.join(__dirname, '../.next');
  const staticDir = path.join(buildDir, 'static');
  
  if (!fs.existsSync(staticDir)) {
    console.warn('Static directory not found');
    return;
  }
  
  const files = fs.readdirSync(staticDir);
  let totalSize = 0;
  
  files.forEach(file => {
    const filePath = path.join(staticDir, file);
    const stats = fs.statSync(filePath);
    totalSize += stats.size;
  });
  
  console.log(`Bundle size: ${(totalSize / 1024 / 1024).toFixed(2)} MB`);
  
  if (totalSize > 5 * 1024 * 1024) {
    console.warn('Bundle size exceeds 5MB limit');
  }
}

analyzeBundle();

5. Vercel CLI를 사용한 로컬 배포 테스트

# 프로젝트 빌드 테스트
vercel build --prod

# 로컬에서 배포 미리보기
vercel dev --port 3000

# 환경 변수 확인
vercel env ls

6. GitHub Actions와 통합

# .github/workflows/vercel-deploy.yml
name: Vercel Deploy
on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Install Vercel CLI
        run: npm install --global vercel
      - name: Pull Vercel Environment
        run: vercel pull --yes --environment=production --token=${{ secrets.VERCEL_TOKEN }}
      - name: Build
        run: vercel build --prod --token=${{ secrets.VERCEL_TOKEN }}
      - name: Deploy
        id: deploy
        run: |
          DEPLOYMENT_URL=$(vercel deploy --prebuilt --prod --token=${{ secrets.VERCEL_TOKEN }})
          echo "url=$DEPLOYMENT_URL" >> $GITHUB_OUTPUT

Lessons Learned

  1. 빌드 캐시 활용: Turborepo의 캐시 기능을 활용하면 빌드 시간을 크게 줄일 수 있습니다.
  2. 환경 변수 검증: 배포 전 필수 환경 변수를 검증하면 런타임 에러를 예방할 수 있습니다.
  3. 번들 분석: 빌드 후 번들 크기를 분석하여 최적화 기회를 발견할 수 있습니다.
  4. 점진적 배포: 대규모 프로젝트에서는 부분 배포를 통해 배포 시간을 줄이는 것이 효과적입니다.

This blog does not accept any external sponsorships, affiliate marketing, or ad revenue.