Skip to content

Conversation

@qowjdals23
Copy link
Collaborator

@qowjdals23 qowjdals23 commented Jan 5, 2026

✏️ Summary

커밋 단계에서 staged 파일만 대상으로 ESLint/Prettier가 자동 실행되도록 Husky + lint-staged를 도입했습니다.


📑 Tasks

🐶 Husky + lint-staged 도입 이유

CI에서 린트/타입체크/빌드가 돌고 있어서 최종 검증은 이미 되고 있지만 !!
CI는 푸시/PR 이후에 결과를 보게 돼서, 작은 실수도 '수정 → push → 다시 확인' 불필요한 왕복이 생길 수 있어요.
그래서 커밋 단계에서 한 번 더 빠르게 걸러주는 용도로 Husky + lint-staged를 추가했습니다.

  • 커밋 단계에서 빠르게 잡기

    • pre-commit에서 먼저 잡으면 CI에서 실패할 만한 자잘한 이슈를 커밋 단계에서 즉시 수정할 수 있어 PR 리뷰/CI 재실행 비용을 줄이는 효과가 있습니다 !
  • 전체 검사 대신 staged 파일만 검사

    • pre-commit에 전체 린트(pnpm lint)를 걸면 속도가 느려지고 커밋 흐름이 끊기기 쉽지, lint-staged는 이번 커밋에 올라가는 파일만 돌려서 부담이 적습니다.
  • 팀 설정을 레포에 고정

    • .git/hooks로 직접 관리하면 팀원마다 달라질 수 있는데, Husky는 .husky/를 레포에 두고 설치 시 자동으로 적용되게 할 수 있어서 팀 단위로 맞추기 좋습니다.
  • Prettier + ESLint

    • 포맷만 맞추는 것보다, ESLint 규칙 위반(금지 패턴)까지 같이 잡는 게 목적이므로 Prettier + ESLint를 함께 묶을 수 있는 lint-staged 조합을 선택했습니다.
    • eslint → prettier 순서로 돌려서, eslint가 고칠 수 있는 건 고치고, 마지막에 prettier로 스타일을 정리하는 흐름으로 맞췄습니다 !

1) Husky 세팅 (Git hooks 버전 관리 + 자동 적용)

  • husky를 devDependency로 설치
  • husky init으로 .husky/ 디렉토리 및 기본 훅 파일 생성
  • 팀원들이 pnpm install만 해도 훅이 적용되도록 prepare 스크립트 기반으로 구성했

2) lint-staged 세팅 (staged 파일만 빠르게 검사)

  • lint-staged를 devDependency로 설치
  • package.json에 lint-staged 규칙 추가
  "lint-staged": {
    "*.{ts,tsx,js,jsx}": [
      "eslint --fix",
      "prettier --write"
    ],
    "*.{json,md,css}": [
      "prettier --write"
    ]
  },

3) pre-commit 훅 연결

  • .husky/pre-commit에서 pnpm exec lint-staged 실행
  • 훅 동작 여부를 터미널에서 명확히 보이도록 로그 메시지 추가
    • 성공했을 때만 “통과” 로그가 찍히도록 && echo 형태로 구성했습니다 !
echo "🐶 Husky pre-commit 실행"
pnpm exec lint-staged && echo "🎉 lint-staged 통과"

👀 To Reviewer

  • 🥲 놓친 부분이 있거나 수정이 필요한 부분 모두 편하게 말씀해주시면 반영하겠습니다!!!!!!!!! 🔥🔥🔥

📸 Screenshot

  • lint-staged 통과 !!
스크린샷 2026-01-06 032416
  • lint-staged 실패..
스크린샷 2026-01-06 032717

🔔 ETC

@github-actions github-actions bot added 🎉INIT 초기 세팅 🐛FIX 기능적 오류, 버그 해결 정민🍐 labels Jan 5, 2026
@github-actions
Copy link

github-actions bot commented Jan 5, 2026

🚀 빌드 결과

린트 검사 완료
빌드 성공

로그 확인하기
Actions 탭에서 자세히 보기

@qowjdals23 qowjdals23 removed the 🐛FIX 기능적 오류, 버그 해결 label Jan 5, 2026
Copy link
Contributor

@hummingbbird hummingbbird left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수고하셨습니다! 실패 시에도 성공 시와 동일하게 '실패..'메시지를 echo로 띄울까 했는데, 어떤 에러가 발생하는지 잘 나타나서 굳이 수정하지 않아도 괜찮을 거 같아요~ 수고하셨어요!

(현재 원격에서 warning 발생하는데 해당 파일에서 ctrl+s 눌러서 수정해주세요!) (eslint/prettier 규칙 위반 경고)
image

Copy link
Collaborator

@odukong odukong left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

필수적으로 설정되어야 할 부분들 꼼꼼히 잘 설정해주신 것 같아요! 수고 많으셨어요😄
특히 ts/tsx 파일은 lint, prettier을 모두 수행하고, json, md, css처럼 포맷 중심의 파일들은 prettier만 동작할 수 있도록 역할 분리시켜준 부분, 좋은 것 같습니다👍🏻👍🏻

추가적으로 이건 정말!! 개인적인!!!의견인데!!!
제가 매번 커밋 메시지 쓸 때 이슈번호를 빼먹은 적이 한 두번이 아니라ㅠㅠ💦
.husky폴더 아래 커밋 메시지에 대한 훅인 commit-msg파일을 생성하고, 저희 커밋 메시지 컨벤션이 맞는지 체크해주는 로직을 추가해주면 좀 더 편하게 작업할 수 있을 것 같아요👉🏻👈🏻

#!/bin/sh

COMMIT_MSG_FILE=$1
COMMIT_MSG_HEADER=$(grep -v '^\s*#' "$COMMIT_MSG_FILE" | head -n 1)

# Merge나 Revert 커밋은 검사하지 않고 통과시킴
if echo "$COMMIT_MSG_HEADER" | grep -Eq "^(Merge|Revert)"; then
  exit 0
fi

PATTERN='^(init|feat|fix|design|update|remove|add|move|rename|docs|comment|refactor|test|chore|deploy|): .+ \(#[0-9]+\)$'

# 커밋 컨벤션과 일치하는지 체크
if ! echo "$COMMIT_MSG_HEADER" | grep -Eq "$PATTERN"; then
  echo "🚨 [커밋 메시지 에러] 형식이 컨벤션과 다릅니다."
  echo "👉 규칙: <타입>: <내용> (#<이슈번호>)"
  echo "👉 예시: feat: 공통 컴포넌트 퍼블리싱 (#1)"
  exit 1
fi

Comment on lines 1 to 2
echo "🐶 Husky pre-commit 실행"
pnpm exec lint-staged && echo "🎉 lint-staged 통과"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

현재 방식 && 조건만으로도 린트 에러가 발생하면 스크립트가 자체적으로 commit을 종료해줄 것 같은데
commit action이 확실히 중단될 수 있도록 실패 케이스(||)에 대해 exit 1을 명시해주는 건 어떨까요?

Suggested change
echo "🐶 Husky pre-commit 실행"
pnpm exec lint-staged && echo "🎉 lint-staged 통과"
echo "🐶 Husky pre-commit 실행"
pnpm exec lint-staged || exit 1
echo "🎉 lint-staged 통과"

명시적으로 exit 1을 걸어주면 린트검사를 통과하지 못했을 때 확실하게 커밋을 막을 수 있을 것 같습니다! 😄

추가적으로 해당 브랜치 pull받아서 확인했을 때,
error: cannot spawn .husky/pre-commit: No such file or directory에러가 발생하더라구요.
환경에 따라 스크립트를 실행할 쉘을 지정해주지 않으면 위와 같은 에러와 함께 스크립트가 실행되지 않을 수 있어서 스크립트 상단에 #!/bin/sh를 추가해주면 좋을 것 같아요!

Suggested change
echo "🐶 Husky pre-commit 실행"
pnpm exec lint-staged && echo "🎉 lint-staged 통과"
#!/bin/sh
echo "🐶 Husky pre-commit 실행"
pnpm exec lint-staged || exit 1
echo "🎉 lint-staged 통과"

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

말씀해주신 대로 exit 1로 실패 케이스를 명확히 끊어주고 ! #!/bin/sh도 추가해서 실행 환경에 따라 훅이 흔들리지 않게 수정했습니다 !
그리고 찾아보니 cannot spawn .husky/pre-commit: No such file or directory는 줄바꿈(CRLF/LF) 때문에 발생하는 케이스도 있다고 해서 줄바꿈도 CRLF -> LF로 함께 수정했습니다 ! 🙂

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

@u-zzn
Copy link
Collaborator

u-zzn commented Jan 7, 2026

세팅하시느라 수고 많으셨습니다아 😽
pre-commit에서 pnpm exec lint-staged로 실행하고 성공 시에만 통과 로그가 찍히도록(&& echo ...) 구성해서 훅 동작 여부를 즉시 확인할 수 있어서 좋네요 👍

필수적인 요소들은 세팅이 다 잘되어 있는 것 같고, 아래에 간단한거 하나만 확인 부탁드립니다 :)

Comment on lines 13 to 21
"lint-staged": {
"*.{ts,tsx,js,jsx}": [
"eslint --fix",
"prettier --write"
],
"*.{json,md,css}": [
"prettier --write"
]
},
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lint-staged 설정 깔끔하네요! 특히 eslint → prettier 순서로 구성해서, eslint에서 자동 수정 가능한 부분을 먼저 처리하고
마지막에 prettier로 스타일을 맞추는 흐름 좋습니다 👍

이 부분은 지극히 개인적으로 추가하면 더 좋을 것 같은 부분인데, repo에서 만약 scss / yaml(yml) / mdx 등을 사용한다면 포맷 대상에 해당 확장자들을 함께 포함해두는 것도 좋을 것 같아요 :)
현재까지 실제 사용하는 확장자 기준으로만 추가하면 충분할 것 같습니다! 현재 기준으로는 아래와 같이 되겠네요 ☺️

"lint-staged": {
  "*.{ts,tsx,js,jsx}": [
    "eslint --fix",
    "prettier --write"
  ],
  "*.{json,md,mdx,css,yml,yaml}": [
    "prettier --write"
  ]
}

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

말씀해주신 것처럼 scss/yml/yaml/mdx도 커밋에서 같이 포맷되면 편할 것 같아서 prettier 대상 확장자에 추가로 반영해뒀습니다 ! 감사합니다 🤩

@qowjdals23
Copy link
Collaborator Author

qowjdals23 commented Jan 8, 2026

추가적으로 이건 정말!! 개인적인!!!의견인데!!! 제가 매번 커밋 메시지 쓸 때 이슈번호를 빼먹은 적이 한 두번이 아니라ㅠㅠ💦 .husky폴더 아래 커밋 메시지에 대한 훅인 commit-msg파일을 생성하고, 저희 커밋 메시지 컨벤션이 맞는지 체크해주는 로직을 추가해주면 좀 더 편하게 작업할 수 있을 것 같아요👉🏻👈🏻

헉 너무너무 좋은 의견이에요… 저도 커밋 메시지에 이슈 번호 누락한 적이 꽤 있어서 추가하면 너무 좋은 것 같네요 ! 바로 반영했습니다 !!!! ❤️‍🔥❤️‍🔥 감사합니다 !

@qowjdals23
Copy link
Collaborator Author

qowjdals23 commented Jan 8, 2026

추가로 팀에 Windows/Mac이 섞여 있다 보니, Husky 훅 파일이 CRLF로 저장되면 macOS/Linux에서 실행할 때 shebang(#!/bin/sh) 라인에 \r가 붙어서 ^M이 인터프리터 경로의 일부로 인식될 수 있더라구요. 그러면 bad interpreter(/bin/sh^M) 같은 에러가 나거나, 상황에 따라 cannot spawn .husky/pre-commit: No such file or directory처럼 훅 실행 자체가 실패하는 케이스가 있다고 합니다 !

그래서 .gitattributes

.husky/* text eol=lf

를 추가해서 .husky 훅 파일만큼은 LF로 고정되도록 처리했습니다 !!

확인 부탁드립니다아..🫠

@qowjdals23 qowjdals23 merged commit d352c8f into dev Jan 8, 2026
2 checks passed
@qowjdals23 qowjdals23 deleted the init/#16/husky branch January 8, 2026 17:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Init] Husky 세팅

5 participants