Contents
see List왜 커밋 전에 자동 검증해야 할까
코드 품질 검사는 CI에서만 실행해도 되지만, 형식 오류나 명백한 린트 오류를 원격 저장소에 올린 뒤에 발견하면 피드백 주기가 길어진다. 특히 여러 사람이 같은 브랜치를 사용하는 프로젝트에서는 포맷이 제각각인 변경, 사용하지 않는 import, 타입 오류가 작은 수정에도 반복적으로 섞인다. Git 훅은 commit, push 같은 Git 이벤트 직전에 명령을 실행해 이런 오류를 개발자 컴퓨터에서 빠르게 걸러내는 장치다.
다만 Git 훅을 무거운 전체 테스트 실행 도구로 쓰면 커밋 자체가 느려져 우회 옵션이 남용될 수 있다. 실무에서는 커밋 단계에 변경된 파일만 대상으로 포맷과 정적 검사를 실행하고, 전체 단위 테스트·통합 테스트·빌드는 CI 또는 pre-push 단계로 분리하는 방식이 안정적이다. JavaScript와 TypeScript 프로젝트라면 Husky와 lint-staged 조합이 이 구성을 간단하게 만든다.
역할을 분리해 설계하기
- formatter: Prettier처럼 코드 표기를 일관되게 정리한다. 수정 가능한 작업이므로 staged 파일에 결과를 다시 반영할 수 있다.
- linter: ESLint처럼 오류 가능성이 높은 패턴, 불필요한 변수, 잘못된 import를 검사한다.
- type check: TypeScript 컴파일러가 타입 호환성을 확인한다. 프로젝트 전체 문맥이 필요할 수 있어 보통 CI에서 실행한다.
- test: 회귀를 막는 테스트다. 실행 시간이 짧은 핵심 테스트만 pre-push에 둘 수 있지만, 기본은 CI가 적합하다.
lint-staged의 핵심은 Git index에 올라간 파일 목록만 명령에 전달한다는 점이다. 모든 소스 파일에 ESLint를 실행하는 방식보다 빠르고, 이번 커밋과 무관한 기존 경고 때문에 새 변경을 막는 상황도 줄인다. 반대로 의존성 갱신, 설정 파일 변경, 생성 코드 등은 대상 패턴에 포함되는지 별도로 확인해야 한다.
Husky와 lint-staged 설치
npm 기반 프로젝트의 예시는 다음과 같다. 팀에서 사용하는 패키지 관리자가 pnpm 또는 yarn이면 같은 의존성을 해당 명령으로 추가하면 된다. Husky 초기화 뒤 생성된 .husky/pre-commit 파일은 반드시 저장소에 커밋해야 다른 개발자와 CI 환경에서도 동일한 훅 구성을 받을 수 있다.
npm install --save-dev husky lint-staged eslint prettier
npm pkg set scripts.prepare="husky"
npm run prepare
npx husky add .husky/pre-commit "npx lint-staged"최근 Husky 버전에서는 초기화 방식이 달라질 수 있으므로, 설치된 버전의 공식 문서를 확인해 프로젝트의 prepare 스크립트가 실제로 훅을 활성화하는지 검증한다. 중요한 것은 특정 생성 명령이 아니라, 클론 후 npm install만으로 훅이 준비되는 상태를 만드는 것이다.
변경 파일만 검사하는 설정
package.json에 아래 설정을 넣으면 JavaScript·TypeScript 파일은 Prettier로 먼저 수정한 뒤 ESLint 검사를 받고, JSON·CSS·Markdown 파일은 포맷만 적용된다. 명령에 파일 확장자를 직접 고정하지 않고 lint-staged가 전달하는 파일 목록을 사용해야 staged 범위가 유지된다.
{
"scripts": {
"prepare": "husky",
"lint": "eslint .",
"typecheck": "tsc --noEmit",
"test": "vitest run"
},
"lint-staged": {
"*.{js,jsx,ts,tsx}": [
"prettier --write",
"eslint --fix"
],
"*.{json,css,md,yml,yaml}": "prettier --write"
}
}ESLint의 자동 수정 결과가 있으면 lint-staged는 해당 파일을 다시 stage한다. 따라서 커밋 직전 수정이 예상 밖으로 커지는 것을 피하려면 자동 수정 규칙을 제한하고, 처음 도입할 때는 별도 포맷 커밋으로 기존 파일을 정리하는 편이 좋다. 설정 파일 자체를 수정한 뒤에는 의도적으로 오류를 하나 만들어 훅이 실패하는지, 포맷만 바꾼 파일이 자동으로 stage되는지를 확인한다.
pre-push와 CI에 남겨야 할 검증
커밋 훅에는 빠른 검사만 두고, 저장소 전체를 보는 검증은 명령 스크립트로 유지한다. 예를 들어 타입 검사와 테스트를 pre-push에서 실행하려면 아래처럼 구성할 수 있다. 대규모 저장소나 원격 의존성이 있는 테스트는 push 속도를 크게 떨어뜨릴 수 있으므로 CI만 사용하고, 보호 브랜치의 필수 검사로 지정하는 편이 낫다.
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npm run typecheck && npm run test이 파일을 .husky/pre-push로 두면 실패 시 push가 중단된다. 그러나 훅은 사용자가 --no-verify로 건너뛸 수 있고, GUI 클라이언트나 환경 설정에 따라 실행 조건도 달라질 수 있다. 품질 보장의 최종 기준은 Git 훅이 아니라 CI여야 한다. CI에서는 최소한 npm ci, npm run lint, npm run typecheck, npm run test를 독립 단계로 실행해 로그와 실패 원인을 명확히 남긴다.
도입 시 자주 생기는 문제
- 훅이 실행되지 않으면
core.hooksPath가 다른 도구로 덮였는지와prepare스크립트 실행 여부를 확인한다. - 커밋이 지나치게 느리면 전체 검사 명령이 훅에 들어갔는지, glob이 빌드 산출물까지 포함하는지 확인한다.
- 자동 수정 후 파일이 사라진 것처럼 보이면 index와 작업 트리 상태를
git status,git diff --cached로 확인한다. - 모노레포는 루트 훅에서 변경 파일의 패키지 경계를 판별하거나, 각 워크스페이스의 검사 명령을 명시적으로 분리한다.
적용 체크리스트
- pre-commit은 staged 파일의 빠른 포맷·린트만 실행한다.
- typecheck와 전체 테스트는 CI 필수 검사로 유지한다.
- 훅 파일과 package 설정을 함께 커밋해 팀 환경을 통일한다.
- 도입 뒤 정상 커밋, 의도적 린트 오류, 자동 포맷 파일을 각각 검증한다.
- 실행 시간이 늘어나면 대상 범위와 명령을 먼저 측정한 뒤 조정한다.
tool
| No | 작성일 | Title |
|---|---|---|
| 2454 | 2026. 04. 12. | 2026 AI 개발 도구 완전 비교: GitHub Copilot vs Cursor vs Claude Code |
| 2430 | 2026. 04. 11. | Claude Code Agent SDK로 커스텀 AI 에이전트 만들기 |
| 2394 | 2026. 04. 09. | 2026년 필수 CLI 도구 12선 - ripgrep, fzf, lazygit부터 AI 코딩 에이전트까지 |
| 2373 | 2026. 04. 08. | 2025-2026 개발자 필수 도구 가이드: AI 코딩 에이전트, CLI 도구, DevOps 플랫폼 총정리 |
| 2341 | 2026. 04. 06. | Claude Code CLI 2026 완벽 가이드 - 설치부터 MCP, 커스텀 에이전트까지 |
| 2327 | 2026. 04. 05. | 2026 필수 모던 CLI 도구 10선: bat, fzf, eza부터 AI 터미널까지 |
| 2306 | 2026. 04. 05. | Docker Compose v2 고급 활용법: 프로파일, Watch, GPU 지원까지 |
| 2305 | 2026. 04. 05. | 2026년 필수 CLI 도구 모음: 터미널 생산성을 10배 높이는 모던 명령어 |
| 2280 | 2026. 04. 04. | Docker Compose v2 실전 가이드: 멀티 컨테이너 개발 환경 구축부터 프로덕션까지 |
| 2279 | 2026. 04. 04. | Claude Code 완벽 가이드: AI 코딩 에이전트로 개발 생산성 10배 올리기 |