Husky에서 pre-commit 속도를 개선해보자

최정은·2026년 1월 5일

1. 개요

현재 회사 프로젝트는 안정적인 코드 품질 유지를 위해 husky를 이용한 pre-push 체크를 수행하고 있다. 하지만 체크 과정에서 약 4분 30초가 소요됨에 따라 개발자의 집중력이 저하되고 배포 흐름이 끊기는 문제가 발생하여 이를 최적화하기로 했다.

2. 현황 및 문제점 분석

개선 전 소요 시간 (Total: 약 4분 23초)

빌드 관련 작업(build:packages + web + storybook)이 전체의 43%를 차지하며, TypeScript Check 역시 빌드 시간과 맞먹는 시간을 소요하고 있었다.

작업 항목소요 시간비중
Prettier Check~40초15%
ESLint Check~47초18%
pnpm install~4초2%
build:packages~58초22%
web build~37초14%
storybook build~18초7%
TypeScript Check~59초22%

문제점: 파일 변경 여부와 상관없이 매번 전체 프로젝트에 대해 빌드 및 린트 검사를 수행하여 불필요한 리소스 낭비가 발생함.


3. 개선 방향 및 적용 내용

3.1. Turborepo 캐싱 시스템 활용

turbo.json의 캐시 정책을 설정하여, 소스 코드 변경이 없는 패키지는 빌드 과정을 건너뛰고 기존 dist 결과물을 재사용하도록 개선함.

// turbo.json
{
  "tasks": {
    "build": {
      "dependsOn": ["^build"],
      "outputs": ["dist/**"],
      "inputs": ["src/**", "package.json", "tsconfig.json", "vite.config.ts"]
    },
    "typecheck": {
      "dependsOn": ["^build"],
      "cache": true,
      "inputs": ["src/**", "tsconfig.json"]
    },
  }
}

3.2. Git Diff 기반 선택적 검사 (Selective Check)

전체 파일을 검사하던 방식에서 git diff를 활용해 실제 수정된 파일에 대해서만 Lint와 Prettier를 실행하도록 스크립트를 최적화함.

  • 원격 브랜치(origin/dev) 대비 변경분만 추출
  • TypeScript/JavaScript 관련 파일 필터링
  • 변경된 파일이 없을 경우 해당 스탭 스킵
# 변경된 파일만 추출하는 로직 예시
REMOTE_BRANCH=$(git rev-parse --abbrev-ref --symbolic-full-name @{u} 2>/dev/null || echo "origin/dev")
CHANGED_FILES=$(git diff --name-only "$REMOTE_BRANCH"...HEAD)
TS_FILES=$(echo "$CHANGED_FILES" | grep -E '\.(ts|tsx|js|jsx)$' | while read -r file; do
  [ -f "$file" ] && echo "$file"
done)
# xargs를 이용해 변경된 파일만 타겟팅하여 검사
echo "$TS_FILES" | xargs -r npx eslint

4. 개선 결과 및 기대 효과

4.1. 소요 시간 비교 (일반적인 코드 수정 시)

작업 항목개선 전개선 후비고
Lint/Prettier~87초~15초변경 파일만 검사 (Diff)
Packages Build~58초~1초Turbo Cache 활용
Storybook Build~18초~1sTurbo Cache 활용
TypeScript Check~59초~13s변경 파일만 검사
총합약 4분 23초약 1분 11초3분 12초 단축 (73%↓)

4.2. 문서 및 단순 수정 시의 이점

이번 개선의 가장 큰 장점 중 하나는 비코드 파일(Markdown, 단순 설정 등) 수정 시의 극적인 속도 향상이다.

  • Markdown(.md)이나 문서만 수정한 경우:
    • Lint/Prettier 대상에서 제외되어 즉시 통과
    • 소스 코드 변경이 없으므로 Turborepo 빌드 및 Type Check가 1~2초 내에 캐시 히트로 완료
    • 결과: push 프로세스가 10~20초 내외로 종료되어 문서 작업의 흐름을 방해하지 않음

0개의 댓글