저는 몇 가지 나쁜 습관이 있습니다. 기능을 완성하고 기분이 좋아서 빌드를 잊고 무심코 푸시를 하거나, 린트를 자주 무시하는 습관입니다. 이러한 습관으로 인해 발생한 에러를 잡느라 시간을 낭비하게 되면 자기 자신에게 짜증이 나곤 합니다.
이러한 문제를 의식적으로 극복하려 노력했지만, 쉽지 않았습니다. 그래서 차라리 강제성을 부여하는 방법을 택했습니다. 기술의 힘을 빌려서라도 해결해보자는 생각입니다.
husky와 lint-staged 도입
'내가 계속 까먹잖아?'
'(컴퓨터가) 강제로 하게하면 돼'
그렇게 husky를 도입하게 되었습니다. husky는 Git hooks를 설정할 수 있게 해주는 도구로, 커밋 전, 푸시 전 등 특정 시점에 자동화된 작업을 실행할 수 있습니다.
특히, pre-commit 시에는 리소스를 낭비하지 않고, 스테이징된 파일만 린트할 수 있어서 lint-staged도 함께 도입했습니다.
husky와 lint-staged에 대하여 설명한 글은 많습니다. 하지만 굳이 제가 이 글을 작성하게 된 이유는, npm run build를 설정하면서 겪은 어려움 때문입니다.
삽질했던 잘못된 코드
# .husky/pre-push
npx lint-staged
# package.json
"lint-staged": {
"*.{ts,tsx}": [
"eslint --fix"
npm run build
]
}
삽질했던 코드에서는 빌드 시 .next 폴더가 스테이징된 파일 주소 아래에 계속 생성되어 errno: -20, code: 'ENOTDIR' 에러가 발생했습니다.
이를 해결하기 위해 next.config.js, tsconfig.json, .eslintrc 파일을 뒤지며 반나절을 삽질을 했습니다. 설정 파일들을 잘 조작해서 .next가 생성되는 곳을 루트 주소로 강제해보려고 했는데 잘 안됐습니다.
그래서 어쨌든 .next 폴더가 루트 디렉토리에 생성되려면 루트에서 Git 조작이 필요할 것 같았고, 그래서 우회적으로 생각해본 결과 .git이 있는 디렉토리가 루트 디렉토리이므로 푸시할 때 빌드를 처리하면 .next가 정상적으로 루트 디렉토리 아래에 생성될 것이라고 예상했습니다.

푸시 전에 Husky를 이용해 빌드를 실행하도록 설정했더니 예상대로 작동했습니다.
그리고 나서 한숨을 돌리고 여유가 생기니 문제의 원인을 정확히 깨달을 수 있었습니다. lint-staged 설정에서 빌드 명령을 함께 작성했기 때문에 오류가 발생한 것이었습니다. 문제는 빌드를 실행하려고 했던 시점이었습니다. lint-staged는 스테이징된 파일에만 동작하도록 설계되었기 때문에, 빌드 명령은 위치가 잘못되었고 경로 충돌 문제를 일으켰던 것입니다.
정상 코드
# .husky/pre-push
npx lint-staged
npm run build
# package.json
"lint-staged": {
"*.{ts,tsx}": [
"eslint --fix"
]
}
또한, 돌이켜보니 "커밋 전에 꼭 빌드해야 한다"는 생각에 다소 집착했던 것 같습니다. 커밋마다 빌드 검사를 실행하는 것보다, 푸시 전에 한 번 빌드 여부를 확인하는 것이 더 경제적이고 합리적입니다. 어제 무지성으로 푸시했다가 배포 에러로 시간을 낭비했던 경험이 저를 집착하게 한 것 같네요.
혹시 저와 비슷한 고민을 하고 계신 분들이라면, 아래 Husky 설정이 문제 해결에 도움이 되기를 바랍니다.
.husky/.pre-commit
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
echo '🙃 ESLINT를 준수합시다'
npx lint-staged ||
(
echo '🚨🚨🚨🚨🚨 린트 실패 🚨🚨🚨🚨🚨';
false;
)
# If everything passes... Now we can commit
echo '🤭🤭🤭🤭🤭🤭 어허? 내 코드 낫배드ㅎ 🤭🤭🤭🤭🤭'
.husky/.pre-push
echo '🙃 빌드를 생활화'
next build ||
(
echo '🚨🚨🚨🚨🚨 빌드 실패 🚨🚨🚨🚨🚨';
false;
)
# If everything passes... Now we can commit
echo '🤭🤭🤭🤭🤭🤭 어허? 빌드 성공 🤭🤭🤭🤭🤭'
이 설정을 팀 프로젝트에 도입했다면 정말 유용했을 것 같습니다. 앞으로 유용하게 활용할 것 같습니다.
