협업을 하다 보면 다른 분의 브랜치에서 pull 한 코드에 오류가 있다든지 (eslint 나 prettier 등 불일치 문제) 아니면, push 해서 CI/CD 파이프라인에 프로젝트가 올라갔는데 마지막 단계에서 빌드가 되지 않아 서버를 띄우지 못하는 불상사가 발생할 수 있다.
이런 현상을 방지하기 위해, 일종의 '규칙 강제' 또는 '선 검증 후 커밋' 느낌으로 사용하는 것이 바로 git hooks 이다. 그리고 husky 는 이러한 git hooks 를 잘 활용할 수 있게 도와주는 도구이다.
즉, git commit
하기 전, git push
하기 전 등과 같은 각종 git 명령어를 사용하는 상황에서 작동하여, 코드에 대한 사전에 정의된 일련의 검사를 하고, 그 결과에 따라 commit 이나 push 를 허용 또는 차단하는 것이다.
그러면 나의 NextJS 프로젝트에 이를 세팅하는 법을 알아보자.
(여기서는 husky 와 함께 lint-staged 까지 같이 설치해볼 것이다!)
(husky 는 전체 파일을 검사하는 데에 비해, lint-staged 는 말 그대로 staging 된 파일들만 검사해서 훨씬 효율적이다!)
우선 본 데모를 위해 빈 Next 프로젝트를 하나 만든다!
npx create-next-app . --typescript --use-npm
husky 는 코드의 오류를 '정해진' 일련의 규칙으로 검사하기 때문에 그 '규칙' 을 우리가 사전에 정해줘야 한다. eslint 의 rule
을 통해 정할 수 있는데, 이를 위해 두 개의 파일을 생성한다. (root 디렉토리에)
.eslintrc.json
{
"extends": ["plugin:@typescript-eslint/recommended", "next/core-web-vitals"],
"plugins": ["@typescript-eslint"],
"parser": "@typescript-eslint/parser",
"rules": {
"no-unused-vars": "off",
"@typescript-eslint/no-empty-interface": "off",
"@typescript-eslint/no-unused-vars": [
"error",
{
"vars": "all",
"varsIgnorePattern": "^_",
"args": "after-used",
"argsIgnorePattern": "^_"
}
],
"require-jsdoc": "off",
"react/display-name": "off",
"quotes": ["error", "single"] // 문자열 들을 단일 따옴표로 감싸도록 강제
}
}
varsIgnorePattern
이 있는데 _
를 붙인 변수면, 사용하지 않은 변수라도 (unused var) 이라도 괜찮다고 해 주겠다는 말이다. 가끔 사용하지 않은 변수를 놔둬야 할 필요도 있는데 그 때 요긴하게 쓸 것이다!
이 규칙들은 본인 (또는 프로젝트 진행 인원들) 의 뜻에 따라 바꿀 수 있다!
.eslintignore
.next
next-env.d.ts
yarn.lock
public
next.config.js
README.md
Dockerfile
.nvmrc
.vscode
.idea
.yarn
.pnp.*
test.tsx
이 파일은 eslint 의 검증 대상 목록에서 제외되는 대상이다. (깨알같이 들어있는 test.tsx
... 내가 나의 컴포넌트를 테스트하는 곳이다!)
prettier 은 많은 분들이 아시다시피 코드의 formatting 을 해 준다. 보통 tabWidth
, doubleQuote
등과 같은 옵션들을 지정할 수 있다.
.prettierrc
{
"trailingComma": "es5",
"useTabs": false,
"tabWidth": 2,
"semi": true,
"singleQuote": true,
"printWidth": 100,
"arrowParens": "always",
"bracketSpacing": true
}
.prettierignore
.next
next-env.d.ts
public
next.config.js
README.md
Dockerfile
.nvmrc
.vscode
.idea
test.tsx
이들도 마찬가지로 prettier 가 formatting 을 수행하지 않을 대상들의 목록이다.
지금가지 총 4개의 파일을 추가해주자!
npm install husky --save-dev
npm install lint-staged --save-dev
그리고 사용할 스크립트들을 넣어 준다. 나는 pre-commit hook 과 pre-push hook 을 쓸 것이다.
다음의 경로에 파일을 추가한다.
.husky/pre-commit
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npx lint-staged
.husky/pre-push
#!/bin/sh
. "$(dirname -- "$0")/_/husky.sh"
npm run build
package.json
수정아래 lint-staged
에 아래 내용 추가. (js, jsx 파일도 linting 을 원할 시 추가해준다!)
{
...
"scripts": {
...
},
"lint-staged": {
"*.{ts,tsx}": [
"eslint",
"prettier --list-different"
]
},
"dependencies": {
...
},
...
}
package.json
에 npm run prepare
추가하기npm pkg set scripts.prepare="husky install"
위를 실행하면 package.json 에 한 줄이 더 추가된다.
"prepare": "husky install"
{
...
"scripts": {
...
"prepare": "husky install"
},
"lint-staged": {
...
},
"dependencies": {
...
},
...
}
이제 eslint 규칙을 위반한 아래와 같은 코드를 짜면
아래와 같이 검사를 하면서
바로 걸려버린다.
커밋 불가!
나는 여기서 npm run prepare
이라는 명령어로 husky 를 설치했지만, 보통의 npm 으로 관리되는 프로젝트들은 사람들이 npm install
로 모든 준비가 끝났으면 한다. 그래서 마지막으로 package.json
에...
{
...
"scripts": {
...
"prepare": "husky install",
"postinstall": "husky install"
},
"lint-staged": {
...
},
"dependencies": {
...
},
...
}
"postinstall": "husky install"
한 줄만 추가해주면 npm install
직후 자동으로 실행되어 이제 다른 사람들은 clone 받은 후 npm install
만으로 husky 가 자동으로 작동한다!
기존에는 husky 만 설치했어서 사용했는데 다음과 같은 두 가지 문제가 있었다.
그래서 이렇게 lint-staged 를 도입하게 되었다!
빠르고, 간편하며, formatting 과 linting 을 동시에 진행할 수 있어서 좋다!
kangdyu 님: 깃허브 방문 하기