ESLint, Prettier, Husky + lint-staged를 활용한 프로젝트 개발환경 세팅 - 2

J·2023년 9월 2일
1

개발환경 세팅

목록 보기
2/2

앞서 ESLint와 Prettier를 설정했지만, 해당 기능들은 결국 개인이 직접 npm run lint && npm run format을 실행해야만 적용된다. 즉 팀원 중 누군가가 해당 명령어를 실행하지 않았거나, 에디터 내 포맷 적용하여 저장(VScode의 경우 'format on save' 옵션) 기능을 사용하지 않았다면 해당 기능들은 무용지물이 된다.

이런 경우를 방지하기 위해 모두에게 적용될 코드, 즉 Github에 올라갈 코드에는 ESLint와 Prettier가 반드시 적용되도록 도와주는 것이 Husky이다.

Husky

Husky improves your commits and more 🐶 woof!
You can use it to lint your commit messages, run tests, lint code, etc... when you commit or push. Husky supports all Git hooks.

공식문서의 내용처럼, Husky는 git commit / push 등의 작업에 test나 lint, format 등 다양한 작업을 적용시킬 수 있다. 즉 Git hook을 좀 더 쉽게 관리할 수 있도록 도와주는 라이브러리라고 할 수 있다.

이번 설정의 경우, 우리는 Husky를 사용해 git commit / git push 이전에(pre-) ESLint와 Prettier를 강제로 적용시키도록 세팅할 것이다.

🤔 Git hook?

  • 간단히 말해 git 작업의 특정 시점에 실행되는 스크립트이다. 예를 들어 git commit을 하기 전 / 후에 특정한 작업을 자동으로 실행하는 것이다.
  • 해당 스크립트를 직접 짜는 것은 설정 및 관리가 버거울 수 있다. 때문에 Husky를 사용해 package.json 내에서 직관적으로 Git hook을 설정 및 관리하고, 결과적으로 프로젝트의 규칙이 강제로 적용되도록 할 수 있다.

Setting

1. ESLint, Prettier의 경우와 마찬가지로 개발환경에서만 적용될 라이브러리이기 때문에 devDependencies에 저장한다.

npm install husky --save-dev

2. Husky에 등록된 hook을 실제 git 프로젝트에 적용시키기 위해 다음의 명령어를 입력한다.
해당 작업은 처음 Husky를 세팅하는 사람에게만 필요한 부분이다.

npx husky install

3. 이후에 해당 프로젝트를 clone하거나 fork 받는 사람들이 npm install을 하면 자동으로 husky가 저장되도록 하기 위해 다음의 명령어를 package.json에 입력한다.

// package.json

{
  "scripts": {
    "postinstall": "husky install", // 해당 부분 추가
    "format": "prettier --cache --write .",
	"lint": "eslint --cache .",
  },
}

4. commit 전에는 Prettier를 적용시키고 git add 까지, push 전에는 ESLint를 적용시키기 위해 다음의 명령어를 실행한다.

  1. npx husky add .husky/pre-commit "npm run format && git add ."
  2. npx husky add .husky/pre-push "npm run lint"

위의 작업을 마치면 이제 git 레포지토리에는 Prettier 포맷이 적용되고 ESLint 문법이 모두 통과된 결과물만이 등록되어, 비로소 모든 팀원에게 동일한 개발환경이 적용된다.


[Appendix] lint-staged

위의 Husky까지만 설정해도 이제 코드 검사는 문제없이 이루어진다. 하지만 코드 검사가 commit과 push 두 단계에 걸쳐서 이루어지는 점, 모든 파일에 검사가 이루어지기 때문에 변경된 파일만 감지하기 위해 --cache . 의 명령어를 추가해야 했던 점 등은 효율성 측면에서 의문이 생길 수 있다.

해당 문제를 해결하기 위해 commit 이 이루어질, 즉 stage에 등록된 파일들에만 ESLint와 Prettier 검사를 실시해 보다 효율적인 코드관리를 할 수 있도록 도와주는 라이브러리가 바로 lint-staged 이다.

Setting

1. 우선 devDependencies로 lint-staged를 설치한다.

npm install lint-staged --save-dev

2. 기존의 .husky 폴더 하위에 있던 pre-commit 파일의 npx 부분을 lint-staged를 적용시키기 위해 다음과 같이 수정한다.

npx lint-staged

  • lint-staged 최신 버전에는 git add 의 기능이 포함돼 있기 때문에 추가적인 명령어를 작성하지 않아도 된다.

3. 기존에 package.json의 scripts에 작성돼 있던 lintformat 키워드는 lint-staged에 통합될 것이기 때문에 삭제한다. 그리고 lint-staged에 ESLint와 Prettier 검사를 실시하기 위해 관련 명령어를 작성한다.
모두 완성된 모습의 package.json 코드는 다음과 같다.

  "scripts": {
    "postinstall": "husky install"
  },
  "lint-staged": {
    "*.js": [
      "eslint --fix",
      "prettier --write"
    ]
  },

*.js

  • 현 프로젝트내의 모든 .js 확장자를 가진 파일들에 해당 내용들을 적용하겠다는 의미이다. 추가로 다른 확장자들을 사용하고 싶다면 다음과 같이 작성하면 된다. 뒤에 적용할 명령어는 두 개 이상일 때는 상기한 것처럼 배열로 감싸안아 작성한다.

    "*.{js,jsx,ts,tsx, ...}": "eslint --fix"

--cache . 명령어 삭제

  • 이제 stage에 등록된 파일들만 검사를 실시할 것이므로 기존의 --cache . 명령어를 사용할 필요가 없다.

4. 기존의 push 단계에서 할 작업이 commit 단계에서 끝나기 때문에, .husky 폴더의 pre-push 파일은 삭제한다.

이렇게 모든 세팅은 끝났고, 인위적으로 ESLint와 Prettier 규칙에 어긋난 코드를 작성해 lint-staged 작업이 어떻게 이루어지는지 확인해 보겠다.


Practice

현재 코드 상에 에러 표시가 나온 부분은 모두 이전에 작성했던 ESLint의 규칙에 위배되는 부분이다.

또한 에러표시는 나오지 않았지만 string type 변수들이 모두 쌍따옴표로 작성돼 있고 중간중간 세미콜론 없이 끝난 코드, 함수의 인자가 한 개인데 괄호가 표시된 부분, 불필요하게 넓은 줄 공백 등은 모두 Prettier 규칙에 어긋나는 부분이다.

현 상태에서 git commit 을 실행하면 어떻게 되는지 결과를 보겠다.

lint-staged 자체에 내장된 테스트가 진행됐지만, 먼저 진행된 ESLint 검사를 통과하지 못해 다음 단계인 Prettier 검사는 실행되지도 않고 바로 종료된 것을 확인할 수 있다.

이제 ESLint를 규칙에 맞게 수정하고 git commit 을 실행할 때 나오는 결과를 보겠다.

ESLint 검사 통과 후 Prettier 역시 문제없이 적용되어 커밋이 완료된 걸 확인할 수 있다.

결과적으로 commit과 push 두 단계에 걸쳐 코드 검사를 수행했던 이전과 달리, stage에 등록된 파일들만 commit 단계에서 동시에 검사를 진행해 보다 직관적이고 효율적인 개발환경을 세팅했다고 볼 수 있다.

0개의 댓글