메인 콘텐츠로 건너뛰기
pnpm build 명령어는 프로젝트를 프로덕션 환경에 배포할 수 있도록 최적화된 코드로 빌드합니다. TypeScript를 JavaScript로 컴파일하고, 불필요한 코드를 제거하여 실행 속도를 높입니다.

기본 사용법

pnpm build
빌드가 완료되면 dist 디렉토리에 최적화된 JavaScript 파일이 생성됩니다.
📁my-project/
📁dist/ - 빌드 결과물
📄JSindex.js
📁models/
📁api/
📁src/ - 원본 소스
📄JSONpackage.json

빌드 과정

빌드는 다음 단계로 진행됩니다:

1. 기존 빌드 결과물 제거

이전 빌드의 잔여 파일을 깨끗하게 제거합니다.
✓ Build artifacts removed successfully.
제거되는 디렉토리:
  • dist/ - API 빌드 결과물
  • web/dist/ - Web 빌드 결과물
  • web-build/ - 복사된 Web 결과물

2. SWC 설정 파일 준비

빌드에 사용할 SWC 설정 파일을 결정합니다.
// 우선순위
// 1. 프로젝트 루트의 .swcrc (커스텀 설정)
// 2. Sonamu 기본 .swcrc (없을 경우)
커스텀 설정 사용:
# 프로젝트 루트에 .swcrc 생성
touch .swcrc
기본 설정 사용:
Using default .swcrc from sonamu package...

3. API 프로젝트 빌드

TypeScript를 JavaScript로 컴파일합니다.
1

빌드 시작

📦 API Server
Building production-ready API
/path/to/project
2

컴파일 실행

swc src -d dist --config-file .swcrc
빌드 도구: SWC - Rust 기반 초고속 TypeScript 컴파일러
3

완료

✓ build completed (2.5s)
✓ API build completed in 2.5s

4. Web 프로젝트 빌드 (선택)

Web 프로젝트가 있는 경우 빌드하고 API 프로젝트로 복사합니다.
1

빌드 시작

🌐 Web Application
Building static web assets
/path/to/project/web
2

Vite 빌드

vite build
정적 에셋을 최적화하고 번들링합니다.
3

파일 복사

web/dist web-build
API 서버에서 서빙할 수 있도록 복사합니다.
4

완료

✓ build completed (8.2s)
✓ copy completed (0.1s)
✓ Web build completed in 8.3s
Web 빌드 결과물:
  • web/dist/ - 원본 빌드 결과
  • web-build/ - API 서버에서 서빙할 복사본

빌드 설정

SWC 설정 커스터마이징

프로젝트 루트에 .swcrc 파일을 생성하여 빌드를 커스터마이징할 수 있습니다.
.swcrc
{
  "jsc": {
    "parser": {
      "syntax": "typescript",
      "tsx": false,
      "decorators": true
    },
    "target": "es2022",
    "loose": false,
    "externalHelpers": false,
    "keepClassNames": true,
    "transform": {
      "legacyDecorator": true,
      "decoratorMetadata": true
    }
  },
  "module": {
    "type": "es6"
  },
  "sourceMaps": true
}
주요 옵션:
옵션설명기본값
target컴파일 타겟es2022
decorators데코레이터 지원true
sourceMaps소스맵 생성true
keepClassNames클래스명 보존true
.swcrc 파일이 없으면 Sonamu가 제공하는 최적화된 기본 설정을 사용합니다.

빌드 결과물

API 빌드 결과

📁dist/
📄JSindex.js - 엔트리포인트
📁models/ - Model 파일들
📄JSuser.model.js
📄JSpost.model.js
📁api/ - API 로직
📄JSsonamu.js
📁entities/ - Entity 정의
📄JSentities.js
📁practices/ - Practice 스크립트
📄JSp1-test.js
특징:
  • TypeScript → JavaScript 변환
  • 데코레이터 변환 완료
  • 소스맵 포함 (.js.map)
  • Import 경로 해석 완료

Web 빌드 결과 (선택)

📁web-build/
📄HTMLindex.html - HTML 엔트리
📁assets/ - 최적화된 에셋
📄JSindex-abc123.js
📄CSSindex-def456.css
📄ICOfavicon.ico
특징:
  • 코드 압축 (minification)
  • 에셋 해싱 (cache busting)
  • Tree shaking (사용하지 않는 코드 제거)

빌드 최적화

1. 타입 체크 분리

빌드 속도를 높이려면 타입 체크를 별도로 수행하세요.
# 타입 체크만 수행 (빠름)
pnpm tsc --noEmit

# 빌드만 수행 (타입 체크 없음)
pnpm build

2. 증분 빌드

변경된 파일만 재빌드하려면 개발 서버를 사용하세요.
# 전체 빌드 (느림)
pnpm build

# HMR 개발 서버 (빠름)
pnpm dev

3. 캐시 활용

SWC는 자동으로 빌드 캐시를 사용합니다.
# 첫 빌드 (느림)
pnpm build  # 5초

# 두 번째 빌드 (빠름)
pnpm build  # 2초

문제 해결

빌드 실패

문제: TypeScript 에러로 빌드 실패
Error: Cannot find module 'some-module'
해결:
# 1. 타입 체크
pnpm tsc --noEmit

# 2. 의존성 확인
pnpm install

# 3. node_modules 재설치
rm -rf node_modules
pnpm install

SWC 설정 에러

문제: .swcrc 설정 오류
Error: Invalid .swcrc configuration
해결:
# 기본 설정으로 복구
rm .swcrc
pnpm build

Web 빌드 실패

문제: Vite 빌드 에러
Error: Could not resolve './some-file'
해결:
# Web 프로젝트 디렉토리로 이동
cd web

# 의존성 확인
pnpm install

# Web만 빌드 테스트
pnpm build

# 루트로 돌아와 전체 빌드
cd ..
pnpm build

빌드 후 실행

빌드가 완료되면 start 명령어로 프로덕션 서버를 실행합니다.
# 빌드
pnpm build

# 실행
pnpm start
프로덕션 실행의 특징:
  • 빠른 시작: 컴파일이 완료된 JavaScript 실행
  • 낮은 메모리: TypeScript 변환 오버헤드 없음
  • 소스맵 지원: 에러 발생 시 원본 파일 위치 표시

직접 실행

pnpm start 대신 Node.js로 직접 실행할 수도 있습니다:
node --enable-source-maps dist/index.js
옵션 설명:
  • --enable-source-maps: 에러 발생 시 원본 TypeScript 파일 위치 표시
  • dist/index.js: 빌드된 엔트리포인트

환경 변수 로드

환경 변수가 필요한 경우:
# dotenv로 .env 파일 로드
node -r dotenv/config --enable-source-maps dist/index.js

# 또는 직접 지정
NODE_ENV=production PORT=3000 node --enable-source-maps dist/index.js

CI/CD 설정

CI/CD 파이프라인을 구성하면 코드를 푸시할 때마다 자동으로 빌드하고 배포할 수 있습니다. GitHub Actions, GitLab CI, Jenkins 등 다양한 도구를 사용할 수 있습니다.

왜 CI/CD가 필요한가?

이점설명
자동화수동 빌드/배포 작업 제거
일관성항상 같은 방식으로 빌드
빠른 피드백빌드 실패를 즉시 확인
안전성테스트 통과 후에만 배포
추적성모든 배포 기록 보존

GitHub Actions

GitHub Actions는 GitHub에 통합된 CI/CD 플랫폼입니다. .github/workflows/ 디렉토리에 YAML 파일을 작성하여 워크플로우를 정의합니다.
.github/workflows/deploy.yml
name: Deploy

on:
  push:
    branches: [main]  # main 브랜치에 푸시할 때 실행

jobs:
  build:
    runs-on: ubuntu-latest
    
    steps:
      # 1. 코드 체크아웃
      - uses: actions/checkout@v3
      
      # 2. pnpm 설치
      - uses: pnpm/action-setup@v2
        with:
          version: 8
      
      # 3. Node.js 설정 (pnpm 캐시 활성화)
      - uses: actions/setup-node@v3
        with:
          node-version: 20
          cache: 'pnpm'
      
      # 4. 의존성 설치
      - run: pnpm install
      
      # 5. 빌드
      - run: pnpm build
      
      # 6. 배포
      - name: Deploy
        run: |
          # rsync로 빌드 결과물 업로드
          rsync -avz dist/ server:/app/
주요 단계 설명:
1

코드 체크아웃

actions/checkout@v3을 사용하여 저장소 코드를 가져옵니다.
2

pnpm 설치

pnpm/action-setup@v2로 pnpm 패키지 매니저를 설치합니다.
3

Node.js 설정

actions/setup-node@v3으로 Node.js를 설치하고 pnpm 캐시를 활성화합니다. 캐시 덕분에 의존성 설치가 훨씬 빠릅니다.
4

의존성 설치

pnpm install로 프로젝트 의존성을 설치합니다.
5

빌드

pnpm build로 프로덕션 빌드를 수행합니다.
6

배포

빌드 결과물을 서버로 업로드합니다. rsync, scp, FTP 등 다양한 방법 사용 가능.

테스트 추가

배포 전에 테스트를 실행하여 버그를 조기에 발견할 수 있습니다:
.github/workflows/deploy.yml
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: pnpm/action-setup@v2
        with:
          version: 8
      - uses: actions/setup-node@v3
        with:
          node-version: 20
          cache: 'pnpm'
      - run: pnpm install
      - run: pnpm test  # 테스트 실행
  
  build:
    needs: test  # 테스트 통과 후에만 빌드
    runs-on: ubuntu-latest
    steps:
      # ... 빌드 스텝

환경별 배포

Staging과 Production 환경을 분리할 수 있습니다:
on:
  push:
    branches:
      - develop    # Staging으로 배포
      - main       # Production으로 배포

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      # ... 빌드 스텝
      
      - name: Deploy to Staging
        if: github.ref == 'refs/heads/develop'
        run: |
          rsync -avz dist/ staging-server:/app/
      
      - name: Deploy to Production
        if: github.ref == 'refs/heads/main'
        run: |
          rsync -avz dist/ prod-server:/app/

Docker

Docker를 사용하면 일관된 실행 환경을 보장할 수 있습니다. 개발, 스테이징, 프로덕션 모두 같은 환경에서 실행됩니다.
Dockerfile
# Stage 1: 빌드 스테이지
FROM node:20-alpine AS builder

WORKDIR /app

# pnpm 설치
RUN npm install -g pnpm

# 의존성 설치 (package.json만 먼저 복사하여 캐시 활용)
COPY package.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile

# 소스 코드 복사
COPY . .

# 빌드
RUN pnpm build

# Stage 2: 프로덕션 스테이지
FROM node:20-alpine

WORKDIR /app

# pnpm 설치
RUN npm install -g pnpm

# 프로덕션 의존성만 설치
COPY package.json pnpm-lock.yaml ./
RUN pnpm install --prod --frozen-lockfile

# 빌드 결과물 복사
COPY --from=builder /app/dist ./dist

# 환경 변수
ENV NODE_ENV=production

# 포트 노출
EXPOSE 3000

# 실행
CMD ["pnpm", "start"]
멀티스테이지 빌드의 장점:
장점설명
작은 이미지 크기빌드 도구를 최종 이미지에서 제외
빠른 배포작은 이미지는 pull/push가 빠름
보안불필요한 개발 도구 제거
레이어 캐싱의존성이 변경되지 않으면 재사용

Docker Compose

데이터베이스와 함께 실행하려면 Docker Compose를 사용합니다:
docker-compose.yml
version: '3.8'

services:
  api:
    build: .
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
      - DATABASE_URL=postgresql://postgres:password@db:5432/myapp
    depends_on:
      - db
  
  db:
    image: pgvector/pgvector:pg16
    environment:
      - POSTGRES_PASSWORD=password
      - POSTGRES_DB=myapp
    ports:
      - "5432:5432"
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  postgres_data:
실행:
# 빌드 및 실행
docker-compose up --build

# 백그라운드 실행
docker-compose up -d

# 중지
docker-compose down

성능 비교

프로덕션 빌드는 개발 서버보다 훨씬 빠르고 효율적입니다.
측정 항목개발 서버프로덕션 빌드차이
시작 시간2-3초0.5초4-6배 빠름
메모리 사용200MB100MB50% 절감
요청 처리느림빠름2-3배 빠름
파일 크기원본압축됨30-50% 작음
프로덕션이 빠른 이유:
  1. 미리 컴파일됨: TypeScript를 실시간으로 변환하지 않음
  2. 코드 최적화: 불필요한 코드 제거, 압축
  3. HMR 오버헤드 없음: 파일 감시 및 재로딩 비용 없음
  4. 프로덕션 모드: Node.js와 의존성들이 최적화 모드로 실행

실제 성능 측정

개발 서버와 프로덕션 빌드의 성능을 직접 비교해보세요:
# 개발 서버 시작 시간 측정
time pnpm dev

# 프로덕션 빌드 + 시작 시간 측정
time (pnpm build && pnpm start)
API 응답 시간 비교:
# 개발 서버
curl -w "\n%{time_total}s\n" http://localhost:3000/api/users
# 예: 0.05초

# 프로덕션
curl -w "\n%{time_total}s\n" http://localhost:3000/api/users
# 예: 0.02초

다음 단계