Blog
3 Husky Convention

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

commitizen_test_3

+ commit convention 형식 오류 해결하기

제가 원한 커밋 메시지 형식은 🔧 chore: husky 설치 및 적용 이었으나, 🔧 chore(custom): husky 설치 및 적용 으로 적용되는 상황이 발생했습니다.

commitizen_test_2

이는 프로젝트 범위(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,
};

이후, 다시 커밋을 진행했을 때는 아래 사진과 같이 원하는 대로 컨벤션이 설정된 것을 확인할 수 있었습니다.

commitizen_test_3

참조