[git] husky로 git hook 설정하기 (+lint-staged)

초코침·2023년 8월 24일
1

git

목록 보기
2/4
post-thumbnail

husky 도입

앞서 eslint, prettier 셋팅 방법에 대해 포스팅을 했습니다!
(husky를 위한 빌드업이었어요)

힘들게 eslint, prettier 설정 셋팅을 했는데 저장할 때 자동 포맷팅 설정이 해제돼 있거나, 까먹음 등등의 이유로 사용하지 않는다면 마음이 아프겠죠..

그래서 린팅과 포맷팅을 강제하기 위해 커밋하거나 푸시하기 전에 린팅과 포맷팅이 무조건 수행되도록 동작을 걸어줄 수 있습니다.


이게 바로 git hook인데요,

git hook은 깃의 특정 이벤트가 발생하기 전/후에 특정 hook을 실행할 수 있게 하는 것을 말합니다.

즉, 커밋 또는 푸시와 같은 깃 이벤트가 발생하기 전에 린팅/포맷팅 같은 특정 동작(hook)을 실행하도록 하는 것이죠.


다만, git hook 설정은 까다롭고 모든 팀원들이 이를 사용하기 위해 한 번씩 수행해야 하는 일련의 과정들이 있습니다.

(린팅/포맷팅 까먹었을 때 하려고 새로 도입한 것을 또 까먹는다면 정말 무용지물이겠죠…..)

따라서 이러한 단점 없이 git hook을 사용하기 위해 husky라는 패키지를 사용합니다.

husky를 사용하면 git hook을 쉽게 설정할 수 있습니다.

husky 설치

패키지를 설치하고 husky에 등록된 hook을 실제 .git에 적용시킵니다.

이 부분은 첫 프로젝트 셋팅 때만 진행하면 됩니다.

yarn add --dev husky
npx husky install

팀원들이 npm install 또는 yarn을 실행할 때 함께 husky install이 진행될 수 있도록 설정하겠습니다.

먼저 package.jsonscripts에 다음 내용을 작성합니다.

// package.json
{
	...
	"scripts": {
		"prepare": "husky install",
		"format": "prettier --write --cache",
		"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
		...
	}
}

그럼 npm install 또는 yarn 실행이 끝난 뒤 husky install이 함께 실행됩니다.


이제 커밋 직전에는 포맷팅, 푸시 직전에는 린팅이 실행되도록 hook을 추가하겠습니다.

npx husky add .husky/pre-commit "yarn run format"
npx husky add .husky/pre-push "yarn run lint"

lint-staged

커밋 직전에 포맷팅하는 것은 스테이지된 파일을 수정하는 것이기 때문에 포맷팅된 수정본은 스테이징되지 않고 새로운 변경 사항으로 등록되며, 포맷팅되기 이전 파일이 커밋됩니다.

따라서 yarn run format이 실행되면 스테이지된 파일들 중 포맷팅된 파일들이 자동으로 스테이지돼야 포맷팅된 파일들을 커밋할 수 있습니다.

이때 먼저 스테이지된 파일들만 포맷팅 후 다시 스테이징할 수 있게 도와주는 패키지가 lint-staged 입니다. (yarn run format & git add . 해 버리면 커밋하지 않으려했던 파일들도 모두 스테이징되기 때문에… 필수적입니다…ㅎ)

lint-staged 사용하기

  1. 패키지 설치

    yarn add --dev lint-staged
  2. .lintstagedrc.json 생성

    프로젝트 최상위 폴더에 다음 파일을 생성하고 prettier 실행 명령어를 적어줍니다.

    // .lintstagedrc.json
    {
      "src/**/*.{js,jsx,ts,tsx,json,css,scss,md}": ["prettier --write --cache ."]
    }
  3. package.json 수정

    pre-commit 이라는 단축키로 lint-staged를 실행할 수 있도록 합니다.

    // package.json
    {
    	...
    	"scripts": {
    		"pre-commit": "lint-staged",
    		...
    	}
    }
  4. /.husky/pre-commit 파일 수정

    커밋 이전에 lint-staged가 실행되도록 합니다.

    (3번 과정을 생략하고 npx lint-staged 넣어도 됩니다.)

    #!/usr/bin/env sh
    . "$(dirname -- "$0")/_/husky.sh"
    
    yarn run pre-commit

이렇게 lint-staged를 hook으로 걸어놓으면 커밋 칠 때 순간적으로 포맷팅된 타겟 파일들을 커밋할 수 있게 됩니다.

조금 귀찮은 과정이지만, 등록하고 나면 모두가 일정하고 정돈된 코드를 쓸 수 있게 되니.. 프로젝트 셋팅 때만 눈 딱 감고 한 번 해 놓는게 좋을 듯 합니다.


commit 해 보기

다음처럼 포맷팅이 안 된 파일을 커밋하면 포맷팅된 파일이 커밋됩니다.

(밑줄은 lint에서 걸리는 것으로, 커밋 시에는 포맷팅만 하도록 설정했기 때문에 밑줄은 남아있는 상황입니다!)

push 해 보기

포맷팅은 됐지만 린팅이 되지 않는 채로 커밋한 App 파일을 푸시하면 다음처럼 lint 에러가 발생해 push에 실패합니다.

린팅 에러와 경고를 해결해 주면 성공적으로 push할 수 있습니다.

(다만 push 직전 린팅을 걸어주니 린팅 없이 커밋한 파일이 있을 때 rebase가 안되더라구요.. 실제 프로젝트에서는 push에 lint 훅을 걸진 않을 것 같습니다..ㅎㅎ)


이외에도 다양한 hook을 걸어줄 수 있습니다.

앞으로 프로젝트할 때 쓸만한 hook이 있다면 husky로 적극 도입해 봐야겠습니다!

profile
블로그 이사중 🚚 (https://sungjihyun.vercel.app)

0개의 댓글