앞서 eslint, prettier 셋팅 방법에 대해 포스팅을 했습니다!
(husky를 위한 빌드업이었어요)
힘들게 eslint, prettier 설정 셋팅을 했는데 저장할 때 자동 포맷팅 설정이 해제돼 있거나, 까먹음 등등의 이유로 사용하지 않는다면 마음이 아프겠죠..
그래서 린팅과 포맷팅을 강제하기 위해 커밋하거나 푸시하기 전에 린팅과 포맷팅이 무조건 수행되도록 동작을 걸어줄 수 있습니다.
이게 바로 git hook인데요,
git hook은 깃의 특정 이벤트가 발생하기 전/후에 특정 hook을 실행할 수 있게 하는 것을 말합니다.
즉, 커밋 또는 푸시와 같은 깃 이벤트가 발생하기 전에 린팅/포맷팅 같은 특정 동작(hook)을 실행하도록 하는 것이죠.
다만, git hook 설정은 까다롭고 모든 팀원들이 이를 사용하기 위해 한 번씩 수행해야 하는 일련의 과정들이 있습니다.
(린팅/포맷팅 까먹었을 때 하려고 새로 도입한 것을 또 까먹는다면 정말 무용지물이겠죠…..)
따라서 이러한 단점 없이 git hook을 사용하기 위해 husky
라는 패키지를 사용합니다.
husky
를 사용하면 git hook을 쉽게 설정할 수 있습니다.
패키지를 설치하고 husky에 등록된 hook을 실제 .git에 적용시킵니다.
이 부분은 첫 프로젝트 셋팅 때만 진행하면 됩니다.
yarn add --dev husky
npx husky install
팀원들이 npm install
또는 yarn
을 실행할 때 함께 husky install
이 진행될 수 있도록 설정하겠습니다.
먼저 package.json
의 scripts
에 다음 내용을 작성합니다.
// 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
사용하기
패키지 설치
yarn add --dev lint-staged
.lintstagedrc.json
생성프로젝트 최상위 폴더에 다음 파일을 생성하고 prettier 실행 명령어를 적어줍니다.
// .lintstagedrc.json { "src/**/*.{js,jsx,ts,tsx,json,css,scss,md}": ["prettier --write --cache ."] }
package.json
수정
pre-commit
이라는 단축키로lint-staged
를 실행할 수 있도록 합니다.// package.json { ... "scripts": { "pre-commit": "lint-staged", ... } }
/.husky/pre-commit
파일 수정커밋 이전에
lint-staged
가 실행되도록 합니다.(3번 과정을 생략하고
npx lint-staged
넣어도 됩니다.)#!/usr/bin/env sh . "$(dirname -- "$0")/_/husky.sh" yarn run pre-commit
이렇게
lint-staged
를 hook으로 걸어놓으면 커밋 칠 때 순간적으로 포맷팅된 타겟 파일들을 커밋할 수 있게 됩니다.조금 귀찮은 과정이지만, 등록하고 나면 모두가 일정하고 정돈된 코드를 쓸 수 있게 되니.. 프로젝트 셋팅 때만 눈 딱 감고 한 번 해 놓는게 좋을 듯 합니다.
다음처럼 포맷팅이 안 된 파일을 커밋하면 포맷팅된 파일이 커밋됩니다.
(밑줄은 lint에서 걸리는 것으로, 커밋 시에는 포맷팅만 하도록 설정했기 때문에 밑줄은 남아있는 상황입니다!)
포맷팅은 됐지만 린팅이 되지 않는 채로 커밋한 App 파일을 푸시하면 다음처럼 lint 에러가 발생해 push에 실패합니다.
린팅 에러와 경고를 해결해 주면 성공적으로 push할 수 있습니다.
(다만 push 직전 린팅을 걸어주니 린팅 없이 커밋한 파일이 있을 때 rebase가 안되더라구요.. 실제 프로젝트에서는 push에 lint 훅을 걸진 않을 것 같습니다..ㅎㅎ)
앞으로 프로젝트할 때 쓸만한 hook이 있다면 husky로 적극 도입해 봐야겠습니다!