husky & lint-staged


Husky란?

Husky는 Git Hooks를 JavaScript로 쉽게 관리할 수 있게 해주는 npm 패키지이다. Git Hooks는 특정 Git 이벤트(commit, push 등)가 발생할 때 자동으로 실행되는 스크립트로, 코드 품질을 유지하는 데 매우 유용하다. Husky를 사용하면 프로젝트의 모든 개발자가 동일한 Git Hooks를 사용할 수 있도록 설정을 공유할 수 있다.

주요 기능

  • 코드 품질 자동화: commit이나 push 전에 lint, test 등을 자동으로 실행
  • 일관된 개발 환경: 모든 팀원이 동일한 Git Hooks 사용
  • 커밋 메시지 표준화: commitlint와 함께 사용하여 커밋 메시지 규칙 강제
  • 적용 방법

    1. 필요한 패키지 설치

    # ESLint, Prettier, Husky 관련 패키지 설치
    npm i -D @typescript-eslint/eslint-plugin eslint-plugin-prettier @typescript-eslint/parser eslint eslint-config-airbnb eslint-config-airbnb-typescript eslint-config-prettier eslint-plugin-html eslint-plugin-import eslint-plugin-jsx-a11y eslint-plugin-react eslint-plugin-react-hooks prettier husky lint-staged

    2. Prettier와 ESLint 설정

  • .prettierrc와 .eslintrc에 설정해준다.
  • 3. .gitignore에 .eslintcache 추가

    # 기존 .gitignore 내용
    # ...
    # ESLint 캐시 파일
    .eslintcache

    ESLint 캐시란?

    ESLint 캐시(.eslintcache)는 ESLint가 이전에 검사한 파일의 정보를 저장하는 파일이다. ESLint를 --cache 옵션과 함께 실행하면 생성된다. 이 캐시 파일은 다음과 같은 이유로 중요하다.

  • 성능 향상: ESLint는 변경된 파일만 다시 검사하므로 실행 속도가 크게 향상
  • 리소스 절약: 대규모 프로젝트에서 모든 파일을 매번 검사하는 것은 시간과 리소스를 많이 소모
  • .gitignore에 추가해야 하는 이유

  • 캐시 파일은 개발자의 로컬 환경에 따라 달라지며, 다른 개발자와 공유할 필요가 없다.
  • 여러 개발자가 같은 캐시 파일을 공유하면 불필요한 Git 충돌이 발생할 수 있다.
  • 캐시 파일은 자주 변경되며 Git 저장소의 크기를 불필요하게 증가시킨다.
  • 캐시 파일은 ESLint 실행 시 자동으로 생성되므로 버전 관리할 필요가 없다.
  • ESLint 캐시를 사용하면서 .gitignore에 추가함으로써, 빠른 린팅 성능을 유지하면서도 Git 저장소를 깔끔하게 관리할 수 있다.

    4. package.json 설정

    {
    "scripts": {
    "postinstall": "husky init && echo 'npx lint-staged' > .husky/pre-commit && echo 'npm run lint' > .husky/pre-push",
    "format": "prettier --write --cache .",
    "lint": "eslint --cache ."
    },
    "lint-staged": {
    "*.{ts,tsx,js,jsx}": [
    "npm run format"
    ]
    }
    }
  • 이렇게 설정하면 npm i 이후 postinstall이 실행되며 husky init이 실행된다.
  • 5. Husky 초기화 및 Hook 설정

    최신 Husky 버전(v9+)에서는 다음과 같이 설정합니다.

    # Husky 초기화
    npx husky init
    # pre-commit hook 설정
    echo "npx lint-staged" > .husky/pre-commit
    # pre-push hook 설정
    echo "npm run lint" > .husky/pre-push

    결과적으로 다음과 같은 파일이 생성됩니다.

  • pre-commit
  • #!/usr/bin/env sh
    . "$(dirname -- "$0")/_/husky.sh"
    npx lint-staged
  • pre-push
  • #!/usr/bin/env sh
    . "$(dirname -- "$0")/_/husky.sh"
    npm run lint

    커밋 컨벤션 강제하기 (선택 사항)

    1. commitlint 패키지 설치

    npm i -D @commitlint/cli @commitlint/config-conventional

    2. commitlint.config.js 설정

    module.exports = {
    extends: ['@commitlint/config-conventional'],
    rules: {
    'type-enum': [
    2,
    'always',
    ['feat', 'fix', 'docs', 'style', 'refactor', 'test', 'chore', 'revert', 'design', 'rename'],
    ],
    },
    };

    3. commit-msg hook 추가

    npx husky add .husky/commit-msg 'npx --no-install commitlint --edit $1'

    유의점

  • Husky v9부터는 설정 방법이 변경되었으므로 버전에 맞는 설정 방법을 사용해야 한다.
  • 팀 전체가 동일한 Husky 설정을 사용하려면 모든 개발자가 npm install 후 Husky가 자동으로 설정되도록 postinstall 스크립트를 사용하는 것이 좋다.