Husky, Lint-staged๋ฅผ ์ด์šฉํ•œ Pre-commit Hook ๊ตฌํ˜„

2023. 1. 18. 01:04ใ†CI, CD/Etc

Eslint๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์‚ฌ์ „์— ์„ค์ •ํ•œ๋Œ€๋กœ ํ”„๋กœ์ ํŠธ ๋‚ด ์ฝ”๋“œ ์Šคํƒ€์ผ์„ ๊ฐ•์ œํ•ด์ฃผ์–ด ์ฝ”๋“œ์— ์ผ๊ด€์„ฑ์ด ์ƒ๊ธฐ๊ณ  ๊ฒฐ๊ณผ์ ์œผ๋กœ๋Š” ํ”„๋กœ์ ํŠธ ๋‚ด ์ฝ”๋“œ ํ’ˆ์งˆ์ด ํ–ฅ์ƒ๋œ๋‹ค. ์ด๋Š” ํŠนํžˆ ํ˜‘์—… ํ™˜๊ฒฝ์—์„œ ๋”์šฑ ๋„๋“œ๋ผ์ง„๋‹ค. 

์ผ๋ฐ˜์ ์œผ๋กœ ๋‹ค์Œ์˜ ๋ช…๋ น์–ด๋ฅผ ์ˆ˜ํ–‰ํ•˜์—ฌ ์ฝ”๋“œ ์Šคํƒ€์ผ์— ๋Œ€ํ•œ ๊ฒ€์‚ฌ๋ฅผ ์ˆ˜ํ–‰ํ•œ๋‹ค.

# --fix ์˜ต์…˜์€ Eslint๊ฐ€ ์ž๋ฐœ์ ์œผ๋กœ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๋Š” ์ˆ˜์ค€์˜ ์Šคํƒ€์ผ ์˜ค๋ฅ˜์— ๋Œ€ํ•ด์„œ๋Š” 
# ์ž๋™์œผ๋กœ ์ˆ˜์ •์„ ํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค. 
eslint --fix

 

๋ณดํ†ต, ํ˜‘์—… ์‹œ์—๋Š” ํ”„๋กœ์ ํŠธ ์ €์žฅ์†Œ์— ์ œ์•ฝ์„ ๋‘์–ด Merge ์‹œ Lint ํ…Œ์ŠคํŠธ๋ฅผ ์ž๋™์œผ๋กœ ์ˆ˜ํ–‰ํ•˜๊ณ  ํ…Œ์ŠคํŠธ๋ฅผ ํ†ต๊ณผํ•˜์ง€ ๋ชปํ•  ์‹œ ์ฝ”๋“œ๊ฐ€ Merge๋˜์ง€ ์•Š๋„๋ก ์„ค์ •ํ•˜๋Š”๋ฐ, ์ด์— ๋”ฐ๋ผ ๋กœ์ปฌ์—์„œ ์ž‘์„ฑํ•œ ์ฝ”๋“œ๋ฅผ ์›๊ฒฉ ์ €์žฅ์†Œ๋กœ pushํ•  ๋•Œ Lint ํ…Œ์ŠคํŠธ๋ฅผ ๊ณ„์†ํ•ด์„œ ์ˆ˜ํ–‰ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค. ์ด๋Š” ๋ฌผ๋ก  ํฐ ์ž‘์—… ๋‹จ์œ„๋Š” ์•„๋‹ˆ์ง€๋งŒ ๋งค๋ฒˆ ์ˆ˜ํ–‰ํ•˜๊ธฐ์—๋Š” ๊ฝค๋‚˜ ๋ฒˆ๊ฑฐ๋กœ์šด ์ž‘์—…์ด๊ณ , ๋˜ ๊ฐ„ํ˜น ํ…Œ์ŠคํŠธ๋ฅผ ์žŠ์–ด๋ฒ„๋ฆฌ๋Š” ๊ฒฝ์šฐ๋„ ์กด์žฌํ•œ๋‹ค. 

์ด๋ฅผ ์œ„ํ•ด ๊ฐœ๋ฐœ์ž๋Š” Husky์˜ ๋„์ž…์„ ๊ณ ๋ คํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

Husky

Husky๋Š” ํ˜‘์—… ํ™˜๊ฒฝ์—์„œ Git Hooks์„ ์‰ฝ๊ฒŒ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋„์™€์ฃผ๋Š” NodeJS ๊ธฐ๋ฐ˜ ๋ชจ๋“ˆ์ด๋‹ค.

์—ฌ๊ธฐ์„œ Git Hooks๋Š” ํŠน์ • Git ์ด๋ฒคํŠธ ์‹คํ–‰ ์ „, ํ›„์— ์ถ”๊ฐ€์ ์ธ ์ž‘์—…์„ ์ž๋™์ ์œผ๋กœ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋Š” ๋„๊ตฌ์ด๋‹ค. Git Hooks์˜ ์ข…๋ฅ˜๋กœ๋Š” ํด๋ผ์ด์–ธํŠธ ํ›…, ์„œ๋ฒ„ ํ›…์œผ๋กœ ๋‚˜๋‰˜๋ฉฐ ๊ทธ ์•ˆ์—์„œ๋„ ์ปค๋ฐ‹ ์›Œํฌํ”Œ๋กœ์šฐ ํ›…, ์ด๋ฉ”์ผ ์›Œํฌํ”Œ๋กœ์šฐ ํ›…, ์„œ๋ฒ„ ํ›… ๋“ฑ์œผ๋กœ ๋‚˜๋‰œ๋‹ค. ์—ฌ๊ธฐ์—์„œ๋Š” ์ปค๋ฐ‹ ์‹œ ์ž๋™์œผ๋กœ Lint ์ฒดํฌ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ๋กœ์ง์„ ์ž‘์„ฑํ•ด์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ปค๋ฐ‹ ์›Œํฌํ”Œ๋กœ์šฐ ํ›…์— ๋Œ€ํ•ด์„œ๋งŒ ์กฐ๊ธˆ ๋” ์•Œ์•„๋ณด์ž.

Commit Workflow Hooks

์ปค๋ฐ‹ ์›Œํฌํ”Œ๋กœ์šฐ ํ›…์„ ํ†ตํ•˜๋ฉด ์ปค๋ฐ‹ ์ด๋ฒคํŠธ ์ „, ํ›„๋กœ ํ›…์„ ์ž‘๋™์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค. ์ปค๋ฐ‹ ์›Œํฌํ”Œ๋กœ์šฐ ํ›…์˜ ์ข…๋ฅ˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  • pre-commit (์ปค๋ฐ‹ ์‹œ ๊ฐ€์žฅ ๋จผ์ € ์‹คํ–‰)
  • prepare-commit-msg (git์ด ์ปค๋ฐ‹ ๋ฉ”์‹œ์ง€๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ํŽธ์ง‘๊ธฐ๋ฅผ ์‹คํ–‰ํ•˜๊ธฐ ์ง์ „ ์‹คํ–‰)
  • commit-msg (์ปค๋ฐ‹์ด ๋ฐœ์ƒํ•˜๊ธฐ ์ง์ „ ์‹คํ–‰)
  • post-commit (์ปค๋ฐ‹์ด ๋ฐœ์ƒํ•œ ์งํ›„ ์‹คํ–‰)

์ด ์ค‘ pre-commit ํ›…์„ ํ†ตํ•˜๋ฉด ์ปค๋ฐ‹ ์ด๋ฒคํŠธ ๋ฐœ์ƒ ์‹œ ๋จผ์ € ํŠน์ • ํ…Œ์ŠคํŠธ๋ฅผ ๊ฐ•์ œํ•˜๊ณ , ํ…Œ์ŠคํŠธ ์‹คํŒจ ์‹œ ํ•ด๋‹น ์ปค๋ฐ‹ ์ด๋ฒคํŠธ๋ฅผ ์ทจ์†Œ์‹œํ‚ค๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ•˜๋‹ค. 

์ด๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ๋„ ์–ด๋ ต์ง€ ์•Š์€๋ฐ, ์ž๋™์œผ๋กœ ํ”„๋กœ์ ํŠธ ํด๋”์— ์ƒ์„ฑ๋˜๋Š” .git ๋””๋ ‰ํ„ฐ๋ฆฌ ๋‚ด๋ถ€์˜ hooks ๋””๋ ‰ํ„ฐ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค. ํ•ด๋‹น ๊ฒฝ๋กœ์— ๊ฐ€๋ณด๋ฉด Git์—์„œ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•œ ์ƒ˜ํ”Œ ํ›… ํŒŒ์ผ๋“ค์ด ์กด์žฌํ•œ๋‹ค. ์ด๋ฅผ ์ ์šฉํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ๋‹จ์ˆœํžˆ ํŒŒ์ผ๋ช…์—์„œ .sample์„ ๋นผ์ฃผ๋ฉด ๋œ๋‹ค. ๋กœ์ง์„ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ๋„ ์–ด๋ ต์ง€ ์•Š์€๋ฐ, shell, Perl ๋ฟ ์•„๋‹ˆ๋ผ Ruby, Python์œผ๋กœ๋„ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

git์—์„œ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•œ sample ํŒŒ์ผ๋“ค

์ง€๊ธˆ๊นŒ์ง€์˜ ๋‚ด์šฉ๋งŒ ๋†“๊ณ  ๋ดค์„ ๋•Œ, Husky๊นŒ์ง€ ๊ฐˆ ํ•„์š” ์—†์ด ๋‹จ์ˆœ Git Hook๋งŒ์œผ๋กœ๋„ ์ถฉ๋ถ„ํ•ด๋ณด์ธ๋‹ค. ํ•˜์ง€๋งŒ ๊ธฐ๋ณธ Git Hook์—๋Š” ํฐ ๋ฌธ์ œ์ ์ด ์กด์žฌํ•œ๋‹ค. ๋ฐ”๋กœ, ์œ„์™€ ๊ฐ™์ด ์ž‘์„ฑ๋œ Git Hook ํŒŒ์ผ์„ Git์„ ํ†ตํ•ด ์›๊ฒฉ ์ €์žฅ์†Œ, ํ˜น์€ ๋‹ค๋ฅธ ์‚ฌ์šฉ์ž์™€ ๊ณต์œ ํ•  ์ˆ˜ ์—†๋‹ค๋Š” ๋ฌธ์ œ๋‹ค. Git ๋ช…๋ น์–ด๋“ค์„ ํ†ตํ•ด์„œ๋Š” .git ๋””๋ ‰ํ„ฐ๋ฆฌ์˜ ํŒŒ์ผ๋“ค์„ ๊ณต์œ ํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์ธ๋ฐ, ํ•ด๋‹น ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด Husky๊ฐ€ ์“ฐ์ธ๋‹ค.

 

 

Husky๋ฅผ ํ†ตํ•œ Git Hook ๊ณต์œ 

Husky๋ฅผ ํ†ตํ•˜๋ฉด ํ˜‘์—… ํ™˜๊ฒฝ์—์„œ Git Hook ๊ด€๋ จ ์„ธํŒ…์„ ๊ต‰์žฅํžˆ ํŽธํ•˜๊ฒŒ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค. Husky ์„ธํŒ…์„ ์ˆ˜ํ–‰ํ•œ ํ”„๋กœ์ ํŠธ๊ฐ€ Git ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด ๊ณต์œ ๋˜๋ฉด, ๋‹ค๋ฅธ ํ™˜๊ฒฝ์—์„œ ์˜์กด์„ฑ ์„ธํŒ…(npm i) ์‹œ ์ €์ ˆ๋กœ Git Hook์ด ์ ์šฉ๋˜๋Š” ๋ฐฉ์‹์ด๋‹ค.

ํ”„๋กœ์ ํŠธ์— Husky๋ฅผ ์ ์šฉํ•ด๋ณด์ž. ์ตœ์ข…์ ์œผ๋กœ๋Š” Husky์™€ Lint-staged๋ฅผ ์ด์šฉํ•˜์—ฌ ๋งค ์ปค๋ฐ‹๋งˆ๋‹ค eslint --fix ๋ช…๋ น์„ ๊ฐ•์ œํ•˜๊ณ  ํ…Œ์ŠคํŠธ๊ฐ€ ์‹คํŒจํ•  ์‹œ ์ปค๋ฐ‹์„ ๋ฐ˜๋ คํ•˜๋Š” ๊ฒƒ์„ ๋ชฉํ‘œ๋กœ ํ•œ๋‹ค.

์šฐ์„ , Husky๊ฐ€ ์‚ฌ์šฉ๋˜๋Š” ํ™˜๊ฒฝ์€ ํฌ๊ฒŒ 2๊ฐœ๋กœ ๋‚˜๋‰œ๋‹ค. ๊ฐ๊ฐ์˜ ๊ฒฝ์šฐ์— ๋Œ€ํ•ด Husky์™€ Lint-staged ์„ค์ •์ด ์กฐ๊ธˆ์”ฉ ๋‹ค๋ฅด๊ฒŒ ์ง„ํ–‰๋œ๋‹ค.

  1. .git ๋””๋ ‰ํ„ฐ๋ฆฌ์™€ package.json ํŒŒ์ผ์ด ๋™์ผ ๋””๋ ‰ํ„ฐ๋ฆฌ์— ์œ„์น˜ํ•˜๋Š” ๊ฒฝ์šฐ
  2. .git ๋””๋ ‰ํ„ฐ๋ฆฌ์™€ package.json ํŒŒ์ผ์ด ์„œ๋กœ ๋‹ค๋ฅธ ๋””๋ ‰ํ„ฐ๋ฆฌ์— ์œ„์น˜ํ•˜๋Š” ๊ฒฝ์šฐ

 

.git ๋””๋ ‰ํ„ฐ๋ฆฌ์™€ package.json ํŒŒ์ผ์ด ๋™์ผ ๋””๋ ‰ํ„ฐ๋ฆฌ์— ์œ„์น˜

ํ•ด๋‹น ๊ฒฝ์šฐ์—๋Š” ์„ค์ • ๊ณผ์ •์ด ๊ฐ„๋‹จํ•ด์ง„๋‹ค. 

๋จผ์ €, ๋‹ค์Œ์˜ ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด Husky์˜ ์„ค์น˜์™€ ์„ค์ •์„ ์ˆ˜ํ–‰ํ•˜์ž.

npx husky-init -y && npm install

์œ„ ๋ช…๋ น์–ด๋ฅผ ์ˆ˜ํ–‰ํ•˜๋ฉด ํ”„๋กœ์ ํŠธ ์˜์กด์„ฑ์— Husky๊ฐ€ ์ถ”๊ฐ€๋จ๊ณผ ๋™์‹œ์—, .husky ๊ฒฝ๋กœ๊ฐ€ ์ƒ์„ฑ๋˜๊ณ  ๊ทธ ์•ˆ์— pre-commit ํŒŒ์ผ์ด ์ƒ์„ฑ๋œ๋‹ค. ์ž๋™์œผ๋กœ ์ƒ์„ฑ๋œ ํŒŒ์ผ์˜ ๋‚ด์šฉ๋ฌผ์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npm test

์ด ๋•Œ npm test ๋ช…๋ น์–ด๋Š” Husky๊ฐ€ ์ž๋™์œผ๋กœ ์ถ”๊ฐ€ํ•œ ๋ช…๋ น์–ด์ด๋‹ค. Husky๋ฅผ ํ†ตํ•ด ๋˜ ๋‹ค๋ฅธ ๋ช…๋ น์–ด๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ๋‹ค์Œ์˜ ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

npx husky add {Husky ํŒŒ์ผ์˜ ๊ฒฝ๋กœ} "{์ˆ˜ํ–‰ํ•  ๋ช…๋ น์–ด}"

์ปค๋ฐ‹ ์‹œ Shell์— Hello, Husky! ๋ผ๋Š” ๋ฌธ์ž์—ด์„ ์ถœ๋ ฅํ•˜๋„๋ก, ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

npx husky add .husky/pre-commit "echo 'Hello, Husky!'"

๋ช…๋ น์–ด ์ˆ˜ํ–‰ ํ›„ ๋‹ค์‹œ .husky/pre-commit ํŒŒ์ผ์— ๊ฐ€๋ณด๋ฉด, ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ช…๋ น์–ด๊ฐ€ ์ถ”๊ฐ€๋œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npm test
echo 'Hello, Husky!'

์ด์ œ ์ปค๋ฐ‹์„ ์‹คํ–‰ํ•˜๋ฉด ์œ„ ๋กœ์ง์ด ์ˆ˜ํ–‰๋œ๋‹ค. 

์ด ๋•Œ, ๋งŒ์•ฝ package.json์˜ npm test ๋ช…๋ น์–ด๋ฅผ ๋”ฐ๋กœ ๊ฑด๋“ค์ง€ ์•Š์•˜๋‹ค๋ฉด ์ผ๊ด„์ ์œผ๋กœ exit 1 ์ด ์ˆ˜ํ–‰๋˜๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ ๋’ค์˜ echo ๋ฌธ์€ ์‹คํ–‰๋˜์ง€ ์•Š๊ณ  ๊ณง๋ฐ”๋กœ ์ปค๋ฐ‹์ด ๋ฐ˜๋ ค๋˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

Lint-staged ์ ์šฉ

Lint-staged๋ฅผ ์ด์šฉํ•˜๋ฉด ํ˜„์žฌ staging ์ƒํƒœ์˜ ์ฝ”๋“œ๋“ค์— ๋Œ€ํ•ด์„œ๋งŒ Lint ์ฒดํฌ๋ฅผ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ฆ‰, ํŠน์ • ์ปค๋ฐ‹์˜ ๋ณ€๋™ ์‚ฌํ•ญ์— ๋Œ€ํ•ด์„œ๋งŒ Lint ์ฒดํฌ๊ฐ€ ์ˆ˜ํ–‰๋˜๋Š” ๊ฒƒ์ด๋‹ค. ๋งค ์ปค๋ฐ‹ ์‹œ ์ „์ฒด ์ฝ”๋“œ์— ๋Œ€ํ•œ Lint ์ฒดํฌ๊ฐ€ ์ˆ˜ํ–‰๋˜๋ฉด ์ด๋ฏธ ๋ฃฐ์„ ํ†ต๊ณผํ•œ ์ฝ”๋“œ๋“ค์— ๋Œ€ํ•œ ์žฌ๊ฒ€์‚ฌ๊ฐ€ ์ด๋ฃจ์–ด์ ธ ์—„์ฒญ๋‚œ ๋น„ํšจ์œจ์ด ๋ฐœ์ƒํ•˜๋Š”๋ฐ, Lint-staged๋Š” ์ด๋Ÿฌํ•œ ๋น„ํšจ์œจ์„ ์ œ๊ฑฐํ•ด์ค€๋‹ค. 

๋˜ํ•œ Lint-staged๋ฅผ ํ†ตํ•ด eslint --fix ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ, eslint๊ฐ€ --fix ์˜ต์…˜์— ์˜ํ•ด ์ˆ˜์ •ํ•œ ์‚ฌํ•ญ๋„ ์ž๋™์œผ๋กœ ์ปค๋ฐ‹์— ํฌํ•จ์‹œ์ผœ์ค€๋‹ค.

Lint-staged๋ฅผ ์„ค์น˜ํ•˜๊ธฐ ์•ž์„œ, ๋จผ์ € ํ•ด๋‹น ํ”„๋กœ์ ํŠธ์— eslint์™€ prettier ์˜์กด์„ฑ์„ ์ถ”๊ฐ€ํ•˜๊ณ  ์„ค์ •์„ ์™„๋ฃŒํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

๊ทธ ๋‹ค์Œ, Lint-staged๋ฅผ ์„ค์น˜ํ•ด์ฃผ์ž.

npm i -D lint-staged

๊ทธ ํ›„ package.json ๋‚ด lint-staged๋ฅผ ์ถ”๊ฐ€ํ•ด์ค€๋‹ค.

{
  ...,
  "lint-staged": {
    "*.{ts,tsx}": [
      "eslint --fix"
    ]
  }
}

๋งˆ์ง€๋ง‰์œผ๋กœ, .husky/pre-commit ํŒŒ์ผ์„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ˆ˜์ •ํ•ด์ฃผ๋ฉด Husky, Lint-staged๋ฅผ ํ†ตํ•œ pre-commit ํ›… ์„ค์ •์ด ์™„๋ฃŒ๋œ๋‹ค.

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

npx lint-staged

์—ฌ๋‹ด์œผ๋กœ, ์œ„ ๋ชจ๋“  ์„ค์ •์€ ์•„๋ž˜์˜ ๋ช…๋ น์–ด ํ•œ์ค„์„ ํ†ตํ•ด์„œ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค. ๋‹จ, ์•„๋ž˜ ๋ช…๋ น์–ด๋Š” .git ๋””๋ ‰ํ„ฐ๋ฆฌ์™€ package.json ํŒŒ์ผ์ด ๊ฐ™์€ ๊ฒฝ๋กœ์— ์กด์žฌํ•  ๋•Œ๋งŒ ์ •์ƒ ์ž‘๋™ํ•œ๋‹ค.

npx mrm@2 lint-staged

 

.git ๋””๋ ‰ํ„ฐ๋ฆฌ์™€ package.json ํŒŒ์ผ์ด ์„œ๋กœ ๋‹ค๋ฅธ ๋””๋ ‰ํ„ฐ๋ฆฌ์— ์œ„์น˜

ํ•ด๋‹น ๊ฒฝ์šฐ๋Š” ์œ„์—์„œ ์–ธ๊ธ‰ํ•œ npx mrm@2 lint-staged ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด husky์™€ lint-staged๋ฅผ ํ•œ๋ฒˆ์— ์„ค์ •ํ•  ์ˆ˜ ์—†๊ณ , ๊ฐ๊ฐ ์„ค์ •ํ•ด์ฃผ์–ด์•ผํ•œ๋‹ค. 

๋” ์‰ฌ์šด ์„ค๋ช…์„ ์œ„ํ•ด ํ”„๋กœ์ ํŠธ๋Š” ๋‹ค์Œ์˜ ๋””๋ ‰ํ„ฐ๋ฆฌ ๊ตฌ์กฐ๋ฅผ ๋”ฐ๋ฅธ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๊ฒ ๋‹ค.

/project
  /.git
  /client
    ...
    /package.json
  /server
    ...
    /package.json

๋˜ํ•œ ์•ž์œผ๋กœ Shell์— ์ž‘์„ฑํ•˜๋Š” ๋ชจ๋“  ๋ช…๋ น์–ด๋Š” .git ๋””๋ ‰ํ„ฐ๋ฆฌ๊ฐ€ ์กด์žฌํ•˜๋Š” project ๋””๋ ‰ํ„ฐ๋ฆฌ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์ด๋ฃจ์–ด์ง„๋‹ค๊ณ  ๊ฐ€์ •ํ•œ๋‹ค.

๋จผ์ € Husky๋ฅผ ์„ค์น˜ํ•ด์ฃผ์ž. client ๋””๋ ‰ํ„ฐ๋ฆฌ์™€ server ๋””๋ ‰ํ„ฐ๋ฆฌ ์ค‘ ํ•˜๋‚˜๋ฅผ ์„ ํƒํ•˜์—ฌ ํ•œ ๊ณณ์—๋งŒ ์„ค์น˜๋ฅผ ์ง„ํ–‰ํ•œ๋‹ค. ์—ฌ๊ธฐ์—์„œ๋Š” server ๋””๋ ‰ํ„ฐ๋ฆฌ๋ฅผ ์„ ํƒํ•˜๊ฒ ๋‹ค.

# /project ๊ฒฝ๋กœ์—์„œ ์‹คํ–‰
cd server && npm install -D husky

๊ทธ ํ›„ ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด Husky ์„ค์ •์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

# ์•ž์„  ๋ช…๋ น์–ด ๋•Œ๋ฌธ์— ํ•ด๋‹น ๋ช…๋ น์ด ์ˆ˜ํ–‰๋˜๋Š” ๋””๋ ‰ํ„ฐ๋ฆฌ๋Š” /project/server
cd .. && npx husky install server/.husky

๊ทธ ๋’ค์—” /server/package.json ํŒŒ์ผ ๋‚ด scripts ๋ถ€๋ถ„์— ๋‹ค์Œ์„ ์ถ”๊ฐ€ํ•œ๋‹ค.

{
  "scripts": {
    ...,
    "prepare": "cd .. && husky install server/.husky"
  }
}

๋‹ค์Œ์€ Lint-staged ๊ด€๋ จ ์„ค์ •์ด๋‹ค. 

Lint-staged๋ฅผ ์„ค์น˜ํ•˜๊ธฐ์— ์•ž์„œ /client ๋””๋ ‰ํ„ฐ๋ฆฌ์™€ /server ๋””๋ ‰ํ„ฐ๋ฆฌ์— ๊ฐ๊ฐ eslint, prettier๋ฅผ ์„ค์น˜ํ•ด์ฃผ๊ณ , ์„ค์ •๋„ ์™„๋ฃŒํ•ด์ค€๋‹ค.

์„ค์ •์ด ์™„๋ฃŒ๋˜์—ˆ๋‹ค๋ฉด, ๊ฐ๊ฐ์˜ ๊ฒฝ๋กœ์— ๋ชจ๋‘ Lint-staged๋ฅผ ์„ค์น˜์™€ ์„ค์ •์„ ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

Lint-staged๋ฅผ /server, /client ๋””๋ ‰ํ„ฐ๋ฆฌ์— ๋ชจ๋‘ ์„ค์น˜ํ•ด์ฃผ์ž.

npm i -D lint-staged

 ๊ทธ ๋’ค์—, ์—ญ์‹œ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ /server, /client ๋””๋ ‰ํ„ฐ๋ฆฌ ๋‚ด package.json์— ๋‹ค์Œ์„ ์ถ”๊ฐ€ํ•ด์ฃผ์ž.

{
  ...,
  "lint-staged": {
    "*.{ts,tsx}": [
      "eslint --fix"
    ]
  }
}

๋งˆ์ง€๋ง‰์œผ๋กœ, /server/.husky/pre-commit ํŒŒ์ผ์„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ˆ˜์ •ํ•ด์ฃผ์ž.

#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

cd client && echo 'Client Check' && npx lint-staged && cd ..
cd server && echo 'Server Check' && npx lint-staged && cd ..

์œ„ ์„ค์ •์„ ํ†ตํ•ด, ์ปค๋ฐ‹ ์‹œ client, server ๊ฒฝ๋กœ์— ๋Œ€ํ•ด ๊ฐ๊ฐ Lint ํ…Œ์ŠคํŠธ๋ฅผ ์ž๋™์œผ๋กœ ์ˆ˜ํ–‰ํ•˜๊ณ  ํ…Œ์ŠคํŠธ๊ฐ€ ์‹คํŒจํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ์ปค๋ฐ‹์ด ์ˆ˜ํ–‰๋˜๊ณ  ๊ทธ๋ ‡์ง€ ์•Š์„ ๊ฒฝ์šฐ ์ปค๋ฐ‹์ด ๋ฐ˜๋ ค๋˜๋Š” pre-commit ํ›…์ด ์ž‘๋™ํ•˜๊ฒŒ ๋œ๋‹ค.