
안녕하세요. SI 업체에 종사한 프론트엔드 1년차 개발자입니다.
빠른 속도의 개발과 클라이언트의 VOC 대응 하느라 많이 바쁜 실무 생활을 보냈었죠.
저 뿐만 아니라 전국에 계신 모든 SI 업체 종사하고 계시는 개발자 분들은 다 이러한 고생들로 사시는 걸로 알고 있습니다. SM, 서비스 뿐만 아니겠죠 뭐...ㅎㅎㅎ
개인적으로 비즈니스 로직과 빌드 테스트, 성능 최적화와 조금의 문서화만 신경쓰더라도 프로젝트 전반적으로의 문제점은 없을거라고 생각했습니다.
하지만 디테일하게 들어간다면 협업 간 사람들과의 의사소통 부재, 프로젝트 코드만 보더라도 서로 다른 스타일로 분석 후 리팩토링만 하더라도 스트레스가 많이 쌓이고, 점점 늘어나는 업무에 처음 적극적이였던 모습과는 달리 점차 소홀해지는 모습들이 보이곤 하죠. 물론 저 또한 그랬습니다.
하지만!!! 그래도 혼자 진행하는 것이 아닌 여러 사람들과 같이 하는 것이라면 최소한의 일에 차질이 없게끔은 해야한다고 저는 생각합니다.
때는 바야흐로 몇달 전.. 제가 휴가를 갔다 돌아온 이후 중간의 프로젝트 진행 확인과 들어온 이슈 체크 및 Staged Files 분석들을 하려고, 같은 팀원 분께 여쭤보는 상황이였습니다.

저와는 그래도 업무상 겹치는 일은 그렇게 많지 않아서 가벼운 마음으로 히스토리 추적하며 분석을 시작으로 업무를 보려는 차....

밑에 더 있지만 그냥 잘라서 올립니다....
후...요즘 같은 각박한 세상에 이런 일이 발생하면 많이 스트레스가 장난 아니겠죠? 허허
최!소!한!이라도 커밋 타입 (fix, feat, chore, refactor 등) 이라도만 알게 해주더라도! 내가 찾는데에만 시간이 조금 덜 걸렸을텐데 말이죠?? 예????!!!
잠시 진정하고...저는 당당히 이러한 상황에는 당당하게 저의 소견을 말해버리는 MZ이기에 분석이 힘들었따! 시간을 너무 많이 잡아먹어따!!! 커밋 컨벤션 부탁드린다!!! 라고 말했던 경험이 떠오르네요.
자 이렇듯. 서로에게 조금의 양보만이라도 해준다면 그래도 같은 식구끼리는 행복하게 지낼 수 있잖아요??
그래서 커밋 시 커밋 컨벤션 검사와 포맷팅이 되도록 해볼겁니다.
husky 라이브러리는 쉽게 말해 우리가 작업한 내용을 올리기 위해 커밋으로 히스토리를 남길텐데 커밋 검사 전 단계를 감지해주는 도구라고 생각하시면 됩니다.
보통 프로젝트를 진행할 때에는 서로간 규칙을 설정하여 이를 문서화로 남기고, 지키기 위해 노력하는데요. 가끔 특정 상황에 대충 남길 때가 분명 있습니다. 저 또한 그랬었구요.(반성하고 있습니다...)
이를 IDE 내 터미널로 git 명령어를 통해 커밋을 남길 때 staged files에 대해 검사하고, 통과되면 커밋 단계로 넘겨주는 친구라고 보면 되겠습니다.
npm i -d husky
yarn add -d husky
pnpm add -d husky
구성하신 패키지 매니저에 따라 명령어를 통해 설치하시면 됩니다.

그럼 이렇게 상위 트리에 .husky로 폴더가 생성되어질 것입니다.
그리고 commit-msg와 pre-commit 파일을 생성했습니다.
pre-commit의 경우는 말 그대로 커밋 이전 단계를 실행해줍니다.

shell 스크립트를 활용해서 만든 간단한 명령어인데.
이는 pre-commit 파일 실행으로 패키지 매니저(pnpm)가 lint-staged 즉, 변경한 파일들을 요점으로 뭔가를 한다는 것이고,
성공했을 때에는 exit 0을 통해 다음으로 넘어가고, 오류가 발생한다면 exit 1를 통해 커밋 명령어가 종료되도록 하는 프로세스입니다.
그렇다면 lint-staged에선 뭘하는지 알려줘야겠죠?
먼저 lint-staged 라이브러리를 설치합니다.
npm i -d lint-staged
yarn add -d lint-staged
pnpm add -d lint-staged
그러고 나서 package.json에서 lint-staged가 실행될 때 뭘 할 것인지 알려줘야합니다.

이것은 원하는 파일 확장자를 구분해서 eslint 검사와 prettier 자동 포맷팅 하도록 설계를 한 것입니다.
저는 js, jsx, ts, tsx 파일들 경우 eslint 검사와 자동 포맷팅 하도록 설정하고, 그 외 파일들은 포맷팅 되도록 했습니다.

.prettierrc에는 간단하게 규칙들을 정의내렸습니다. 그리고 특정 파일들은 적용 안되게 하고 싶다면

.prettierignore 파일을 생성하여 자동 포맷팅 제외하려는 파일들을 작성합니다.


eslint.config.mjs 파일에서는 rules를 통해 코드 설계시 원하는 방향성으로 유도하기 위해 몇 가지 제약사항들을 걸었습니다. 대부분은 경고 줄만 나오게 하기 위해 (안그러면 다른 개발자 분들이 개발 과정에 스트레스를 받을 수도 있습니다.) warn으로 설정합니다.
pnpm add -d @commitlint/cli
pnpm add -d @commitlint/config-conventional
먼저 commitlint 라이브러리를 설치해줍니다.

commit-msg 파일에 커밋 검사하도록 shell script 작성합니다.
npx commitlint --edit &1으로 commit lint를 실행 후 조건문으로 결과 값이 0과 같게 된다면 해당 출력문과 함께 넘기도록 합니다.

그리고 commitlint는 어떻게 검사가 이루어져야하는지 설정을 합니다.
저는 "feat: 어떤 기능을 개발했습니다." 와 같은 conventional commit을 기반으로 작성 유도를 합니다.
headerPattern에는 원하는 커밋 형태를 정규식으로 표현하고, headerCorrespondence는 정규식에 그룹화된 ()를 기준으로 무엇이 들어가는지를 알려주는 겁니다.
그리고 rules의 경우 type은 지정한 타입만 가능하면서 소문자로 무조건 기입 필수로 지정하고, subject도 기입 필수, 마지막으로 전체 길이는 100으로 제한을 걸었습니다.
그럼 이렇게 만들어진 커밋 제약사항들로 다른 개발자 분들이 어떻게 진행해야 하는지 파악하기 빠르기 위해 저는 template도 생성하기로 했습니다.

.gitmessage.txt 파일을 생성 후
1 번째 줄에 개발자 분들이 작성 시 템플릿 내에서 작성하기 편하도록 설명 내용과 함께 마련합니다.
이렇게 된다면 어떤 플로우로 커밋이 진행이 될까요??

커밋하고자 하는 파일을 staged files로 변경 후 git commit 명령어를 입력하면

Lint Success와 함께 자동으로 .gitmessage.txt에서 작성한 템플릿을 활용한 COMMIT_EDITMSG가 나올 것입니다.

해당 안내 설명대로 커밋을 작성해주고, 터미널 내용에는
'hint: Waiting for your editor to close the file...' 라고 나온 것처럼
해당 에디터를 닫아주면

해당 사진처럼 작성한 커밋 메시지 템플릿과 그 뒤에 따라오는 chages commit과 파일 리스트들이 나오고, shell script로 성공 시 알려주기 위한 문구와 함께 커밋이 완료됨을 알 수 있습니다.
만약에 틀리게 한다면 어떻게 될까요??

type을 대문자로 하거나

type 없이 커밋을 남겨서 에디터를 나가게 된다면

설정한 commit lint 제약사항에 따라 type이 없으니 오류 메시지와 함께 커밋을 종료하게 됩니다.
추가적으로 보통 프로젝트를 관리할 때, 개발한 기록을 바로 main 브랜치에 올리지 않고, 다양한 Git 브랜치 전략들로 하위 브랜치에 Pull Request를 통해 리뷰 후 올리는 과정을 진행합니다.
(Hotfix일 경우 바로 올리는 케이스도 있긴 합니다.)
하지만 대부분은 바로 올리는 과정은 매우 리스크가 큰 가능성으로 생각하여 금지하도록 하는데. 실수로 개인 로컬에서 바로 올려버리는 상황도 발생하고는 합니다.
(대부분 개발자 분들은 개인 브랜치 생성 후 작업하고, 원격에 올려서 PR진행을 하기 때문에 이러한 실수는 거의 나타나지는 않기는 합니다.)
이런 케이스를 방지하기 위해서 main에 push를 방지하는 과정도 설계해보려 합니다.

husky 폴더 내에 pre-push 파일을 생성하고, 해당 script를 작성합니다. 이는 브랜치를 검사하여 main 브랜치일 경우에는 안내 출력문과 함께 안되도록 합니다.

또한 커밋 과정에서도 막기를 위해 기존 작성한 스크립트 위에 브랜치 검사를 하도록 추가합니다. 이렇게 된다면 만약 main 브랜치에서 커밋을 하려는 경우

해당 이미지와 같이 안내 내용과 함께 커밋을 종료하게 됩니다.
이렇게 설계를 하게 된다면 개발자는 해당 프로젝트에서 파일에 대한 기록을 남길 때, eslint와 commit lint 검사를 통해 좀 더 안전한 관리가 이루어집니다.
물론! 일부 개발자 분들은 관리에 있어 까다로운 절차라고 하셔서 귀찮아 하시는 분도 있으실테지만 이런 사소한 관리에서도 체계적으로 이루어지게 된다면 전체적으로도 서로간 협업 과정 효율성 증가와 품질 관리 용이성을 나타나지 않을까 하는 생각입니다.
Next.js 프로젝트에서 husky로 원하는 규칙 만들기(feat. eslint, prettier, lint-staged)
Husky로 gitmoji를 포함한 커밋메시지 검사하기1
nextjs 13 typescript 환경에서 eslint airbnb 에 husky, gitmoji, lint-staged까지?