Husky로 컨벤션 지키기
Husky란, git hooks를 적용하게 해주는 라이브러리입니다.
Git hooks란?
- git과 관련된 이벤트가 발생했을 경우, 특정 스크립트를 실행할 수 있는 기능입니다.
- 대표적인 훅으로는
commit-workflow-hook
이 있는데, 이는 커밋 명령어를 통해 커밋을 진행될 때 실행됩니다.- pre-commit : 커밋 메시지를 작성하기 전 실행
- prepare-commit-msg : 커밋 메시지를 생성한 후, 편집기를 실행하기 전 실행
- commit-msg : 커밋 메시지를 완성한 후, 커밋을 최종 실행하기 전에 실행
- post-commit : 커밋을 완료한 후 실행
1. 커밋 전에 eslint, prettier 체크하기
eslint, prettier 규칙은 이미 설정이 되어있는 상태에서 진행합니다.
1. lint-staged 설치
$> pnpm add -D lint-staged
2. lint-staged package.json에 등록
{
"name": "telme",
"version": "0.1.0",
"private": true,
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint",
},
"lint-staged": {
"*.{ts,tsx}": [
"prettier --write",
"eslint --fix"
]
},
"dependencies": {
...
},
"devDependencies": {
...
"lint-staged": "^15.2.10",
},
}
2. Husky 설치하기
$> pnpm add -D husky
$> npx husky init
이렇게 하면 scripts에 prepare이 등록됩니다.
"scripts": {
"prepare": "husky",
},
3. commit-msg hook 등록하기
커밋 메시지를 hook으로 관리하여 컨벤션을 맞춰보고자 합니다.
대부분의 커밋 컨벤션은 chore: ...
과 같은 형태로 맞춰지고 있는데, 여기서 더 나아가서 gitmoji 기반의 커밋 컨벤션을 적용하려고 합니다.
gitmoji
란 커밋 메시지 앞에 이모지를 붙이는 라이브러리로, 직관적으로 어떤 기능을 하는 커밋인지 알 수 있다는 장점이 있습니다.
1. commitlint, commitlint-config-gitmoji 설치
- commitlint : 커밋메시지가 규칙대로 잘 적용되었는지 확인
- commitlint-config-gitmoji : 깃모지 커밋메시지 컨벤션
$> pnpm add -D commitlint commitlint-config-gitmoji
2. commitlint.config.js에 gitmoji 설정 추가
$> echo "module.exports = {extends: ['gitmoji']}" > commitlint.config.js
3. commit-msg husky에 hook 추가
npx --no-install commitlint --edit $1
이제 커밋 컨벤션을 맞게 적었는지 확인할 수 있습니다.
다음에는 대화형 터미널로 커밋 메시지 컨벤션을 적용하겠습니다.
3. commitizen 추가
commitizen는 CLI에서 커밋할 때 대화형 형식으로 메시지를 입력하여 규칙에 따라 형식으로 커밋 메시지를 작성할 수 있게 합니다.
1. 설치
$> pnpm add -D commitizen cz-customizable
2. package.json에 path 등록
{
//
"config": {
"commitizen": {
"path": "node_modules/cz-customizable"
}
},
},
3. .cz-config.js 에 터미널에 띄울 코드 작성
module.exports = {
types: [
{ name: "feat \t\t✨ 기능추가", value: "✨ feat" },
{ name: "fix \t\t🐛 버그픽스", value: "🐛 fix" },
{
name: "test \t\t✅ 테스트 코드 추가",
value: "✅ test",
},
{
name: "refactor \t🔨 리팩터링",
value: "🔨 refactor",
},
{
name: "style \t💄 스타일 추가 및 수정",
value: "💄 style",
},
{ name: "docs \t\t📝 문서 업데이트", value: "📝 docs" },
{
name: "chore \t🔧 빌드 및 구조 수정",
value: "🔧 chore",
},
],
allowCustomScopes: false,
allowBreakingChanges: ["feat", "fix"],
skipQuestions: ["body"],
subjectLimit: 100,
};
4. commitlint.config.js 규칙 추가
module.exports = {
extends: ["gitmoji"],
rules: {
"header-max-length": [0, "always", 100],
"type-enum": [
2,
"always",
["feat", "fix", "test", "refactor", "style", "docs", "chore"],
],
},
};
5. commitizen을 사용할 수 있도록 husky hook 추가
exec < /dev/tty && node_modules/.bin/cz --hook || true
6. 테스트 해보기
git add .
git commit
+ commit convention 형식 오류 해결하기
제가 원한 커밋 메시지 형식은 🔧 chore: husky 설치 및 적용
이었으나, 🔧 chore(custom): husky 설치 및 적용
으로 적용되는 상황이 발생했습니다.
이는 프로젝트 범위(scope) 선택 과정을 건너뛰지 않아 발생한 상황이었습니다.
fix(server): send cors headers
feat(blog): add comment section
해당 프로젝트의 경우, 위 과정이 필요없다고 판단했기 때문에 이를 체크하는 과정을 건너뛰도록 적용하였습니다.
module.exports = {
types: [
...
],
allowCustomScopes: false,
allowBreakingChanges: ['feat', 'fix'],
skipQuestions: ['body', 'scope'], // scope 질문 건너뜀
subjectLimit: 100,
};
이후, 다시 커밋을 진행했을 때는 아래 사진과 같이 원하는 대로 컨벤션이 설정된 것을 확인할 수 있었습니다.