Husky로 Git Hooks 적용하기 🐶


개발을 하다 보면 VS Code의 ESLint가 가끔 제대로 동작하지 않는 경우가 있습니다. 이는 저만의 문제가 아니라 팀원 모두가 공통적으로 겪고 있던 이슈였습니다. 특히 대규모 프로젝트에서는 VS Code의 ESLint 확장 프로그램이 메모리 부족이나 성능 문제로 제대로 작동하지 않는 경우가 종종 발생하는 것 같습니다. 저의 경우 이 상태에서 VS Code의 Developer: Reload Window 를 하면 일시적으로 해결되곤 했습니다.

그러나 이런 상황에서 개발자들은 lint 에러를 인지하지 못한 채로 코드를 push하게 되고, GitHub Actions에서 빌드가 실패하는 것을 확인하게 됩니다. 빌드 체크에 약 5분 정도 소요되는데, 이런 상황이 반복되면서 개발 생산성이 저하되는 문제가 있었습니다.

Husky 소개

Husky는 이러한 문제를 해결하기 위한 도구입니다. Husky는 Git Hooks를 쉽게 설정할 수 있게 해주는 npm 패키지로, 특정 Git 명령(commit, push 등)이 실행되기 전에 지정된 스크립트를 자동으로 실행합니다. Git Hooks는 Git 워크플로우의 특정 시점에 자동으로 실행되는 스크립트입니다.

  • pre-commit: 커밋 전에 실행되는 훅으로, 코드 포맷팅이나 린트 검사에 유용합니다.
  • pre-push: 푸시 전에 실행되는 훅으로, 더 광범위한 린트 검사나 테스트에 활용할 수 있습니다.
  • commit-msg: 커밋 메시지를 검증하는 데 사용됩니다.
  • Husky를 사용하면 이러한 Git Hooks를 JavaScript로 쉽게 관리할 수 있습니다. Husky에 대해서는 아래 포스팅에서 조금 더 자세하게 다루고 있습니다.

    lint-staged 설정

    Husky와 함께 사용하는 중요한 도구로 lint-staged가 있습니다. lint-staged는 Git의 Staged 상태인 파일들에 대해서만 린트 검사를 실행하는 도구입니다. 프로젝트에서 다음과 같이 .lintstagedrc 파일을 설정했습니다.

    {
    "*.{ts,tsx}": ["prettier --cache --write", "eslint --fix --cache"]
    }

    이 설정은 커밋 시 스테이징된 TypeScript 및 TSX 파일에 대해

  • 먼저 Prettier로 코드 포맷팅을 자동으로 수정합니다.
  • 그 다음 ESLint로 코드 품질 문제를 검사하고 가능한 경우 자동으로 수정합니다.
  • 여기서 중요한 점은

  • -cache 옵션을 사용하여 성능을 최적화합니다.
  • -write와 --fix 옵션으로 가능한 문제는 자동으로 수정합니다.
  • Husky 적용 후 개선된 점

    Husky 적용 전에는 다음과 같은 상황이 자주 발생했습니다.

  • 개발자가 코드 작성 후 커밋 및 푸시
  • GitHub Actions에서 린트 에러로 빌드 실패 (약 5분 소요)
  • 개발자가 에러를 확인하고 수정
  • 다시 커밋 및 푸시
  • 빌드 성공 확인 (추가 5분 소요)
  • Husky 적용 후에는 다음과 같이 개선되었습니다.

  • 개발자가 코드 작성 후 커밋 시도
  • Husky가 pre-commit 훅에서 lint-staged 실행
  • 간단한 포맷팅 문제는 자동으로 수정되어 커밋됨
  • 수동 수정이 필요한 문제가 있으면 커밋이 중단되고 즉시 피드백 제공
  • 개발자가 문제 수정 후 다시 커밋
  • 푸시 후 GitHub Actions에서 빌드 성공
  • 이렇게 불필요한 빌드 실패와 대기 시간을 줄임으로써, 개발 생산성이 크게 향상되었습니다. 데이터로 확인해보니 Husky 적용 후 GitHub Actions의 빌드 성공률이 크게 향상되었다는 것을 알 수 있었습니다.

  • 적용 전: 약 88% 빌드 성공률 (1940/2199)
  • 적용 후: 약 93% 빌드 성공률 (637/686)
  • 이는 개발자들이 로컬 환경에서 미리 lint 에러를 발견하고 수정할 수 있게 되어, 불필요한 빌드 실패를 줄일 수 있었기 때문입니다.

    남아있는 7%의 빌드 실패 해결 방안

    Husky 적용 후에도 여전히 약 7%의 빌드 실패가 발생하고 있습니다. 로그를 분석해본 결과, 이러한 실패는 주로 타입 에러에서 기인하는 것으로 확인되었습니다.

    이를 해결하기 위해 추후에는 pre-push 훅에 타입 체크를 추가하는 방안을 고려 중입니다. package.json에 tsc --noEmit 명령을 실행하는 스크립트를 추가하고, 이를 pre-push 훅에서 실행되도록 설정하면 나머지 7%의 빌드 실패도 상당 부분 해결할 수 있을 것으로 예상됩니다.

    현재 팀원들과 이 방안에 대해 논의 중이며, 개발 경험을 해치지 않는 선에서 코드 품질을 더욱 향상시킬 수 있는 방향으로 개선해 나갈 계획입니다.