프로젝트에 ESLint와 Prettier, Husky 적용하기

신승준·2022년 9월 9일
1
post-thumbnail

프로젝트를 진행하다보면 서로 간의 이해와 소통을 위해 코딩 스타일을 정하곤 한다. 그러나, 코딩 스타일을 구두로 정하고, 팀원들끼리 알아서 개발하다보면 엉켜지고 실수를 하기 마련이다. 이러한 것을 방지하기 위해서 도구에 위임하고 강제시켜야 한다. 그러한 도구에 ESLint와 Prettier, Husky가 있다! 물론 이것 말고도 더 다양한 것이 있으나 자바스크립트 진영에서 보통 쓰이는 것들이다. 대충 어떤 것이고 어떻게 사용해야 하는지 알아보았다. 전혀 어렵지 않다. 설명이 조금 길지만, 결국엔 패키지 설치 + 파일 만들고 설정 + 터미널 명령어 입력이 끝이다.

바쁘면 맨 밑의 결론으로 건너뛰시면 됩니다.

간단 정리

ESLint

자바스크립트로 코딩을 하다보면 var를 쓴다던가, console.log를 지우지 않고 남겨둔다던가, === 대신 ==을 쓴다던가 자잘한 실수들이 발생할 수 있다.

이렇게 자잘한 문법 실수나 굳이 없어도 되는 것들(보풀, lint)을 쓰면 경고해주고 교정해주려는 것이 Linter이다. 그 중 자바스크립트 진영에서 일반적으로 쓰는 것이 ESLint!

Prettier

Code Formatting 툴이다. 하위로 들어가면 2칸씩 띄울지, 4칸씩 띄울지, forEach나 map 등을 쓸 때 인자가 1개이면 괄호를 씌울지 말지, 따옴표는 큰 걸로 쓸지 작은 걸로 쓸지 정해서 강제시키는 것이다.

ESLint에도 코드 포맷팅 기능이 있다. 하지만 Prettier가 코드 포맷팅 영역에선 훨씬 강력하기 때문에 ESLint와 Prettier를 융합해서 사용하는 것이 일반적이다.

Husky

위의 도구들을 쓰다가 잠시 console.log를 확인하기 위해, 혹은 귀찮아서 동작하지 않도록 해버릴 수 있다. 개발자도 사람이다보니 그 상태에서 Github과 같은 원격 저장소에 올려버리게 되면 당연히 지키던 것들이 무용지물로 되어버린다.

Git Hook과 Husky를 통해, ESLint와 Prettier가 동작하도록 강제함으로써 Github에 올라가기 전에 이러한 실수를 방지할 수 있게 해줄 수 있다. eslint 혹은 prettier가 제대로 적용 안되어 있으면 error를 띄워서 git add 혹은 git commit이 안되게 해 Github에 올리지 않도록 해주는 것이다.

  • Git Hook : git commit, git push 등 git 이벤트 발생 전, 후로 특정 스크립트(hook)를 시킬 수 있다. 이러한 스크립트를 Git Hook이라고 한다.

  • Husky : Git Hook 설정을 도와주는 npm package이다. Git Hook 설정을 쉽게 해준다. 다른 팀원이 프로젝트를 받았을 때(git clone 등) npm install을 하면 저절로 Git Hook 설정이 되도록 해줄 수도 있다. 즉 한명이 Git Hook을 적용한 프로젝트를 만들면, 다른 팀원은 npm install만 하면 Git Hook이 적용된 상태에서 개발을 시작할 수 있게 되는 것. 방법은 밑에서 알아보았다.

dependency vs devDependency

여기서 설치할 패키지들은 모두 npm install 패키지이름 --save-dev로 설치할 것이다. 이 때 --save-dev라는 옵션이 붙는데, 이는 package.json에서 dependencies가 아니라 devDependencies에 추가하겠다는 의미이다.

이 둘의 차이는 배포된 프로젝트에 해당 패키지가 들어가느냐 마느냐일 뿐이다. ESLint나 Prettier, Husky는 개발할 때 유용한 도구이다. 프로젝트의 핵심 로직에는 아무런 영향이 없다. 컨벤션이 맞춰진 상태로 배포를 하고 나면, 그 배포된 프로젝트에는 이 도구들이 필요가 없다. 그 땐 컨벤션이 다 맞춰진 상태이고, 로직에 아무런 영향을 끼치지 않으니까! 그래서 devDependencies에 넣어 배포될 때에는 이 패키지들이 포함되지 않도록 하여 용량을 줄일 수 있게 된다.




그렇다면 어떻게?

프론트엔드 개발자를 희망하고, React를 쓰다보니 CRA를 통해 생성된 프로젝트 기반으로 알아보게 되었다.

설치

ESLint

CRA를 통해 프로젝트를 생성했다면 ESLint는 내장되어 있다. 그렇지 않다면 npm install eslint --save-dev으로 설치 해준다.

CLI 뿐만 아니라, vscode에서 코딩하면서 곧바로 에러를 감지하고 싶다면 VSCode Extension에서 eslint를 설치해주자. 그리고 Enable 클릭해서 활성화.

해당 extension을 깔고, 나중에 eslint 설정도 하게 되면 터미널 명령어로 eslint 경고를 맛보는 것 뿐만 아니라, vscode에서 개발하면서 곧바로 내가 어떤 실수를 하고 있는지 알 수 있게 된다.

eslint 설정에 var 쓰면 에러 낼꼬얌이라고 해뒀다. 그러면 위와 같이 var를 통해 변수 선언을 하면 vscode 상에서 에러가 발생한다. extension 설치 안하면 안 뜬다. 터미널에 eslint 명령어를 입력해야 에러가 뜬다. 다음과 같이 npx eslint 파일경로를 입력해주면 된다.

Prettier

CRA로 만들어도 Prettier는 포함되어 있지 않다. 따라서 npm install prettier --save-dev로 설치.

똑같이 vscode에서 코딩하면서 곧바로 prettier를 적용하고 싶다면 vscode extension에서 prettier를 검색해 설치한다.

그리고 cmd + ,를 누르든 뭘 하든 Settings로 들어가 format on save를 체크해주자. 이러면 cmd + s 등 저장할 때마다 prettier가 적용된다. 지금은 따로 prettier의 세세한 설정을 안해줬으니 prettier의 기본 셋팅으로 포맷팅될 것이다.

eslint-config-prettier

앞서 ESLint는 linter 기능 뿐만 아니라 코드 포맷팅 또한 비교적 약하게 지원하고 있다고 말한 바 있다. Prettier랑 같이 사용하면서 충돌이 없애기 위해 또다른 패키지가 필요하다. 그것이 eslint-config-prettier이다. npm install eslint-config-prettier --save-dev를 입력해주자.

Husky

npm install husky --save-dev


설정

설치는 끝났으니, 이제 각각의 패키지마다 세세한 설정을 해보자.

ESLint

프로젝트의 루트, 그러니까 package.json이 있는 곳에 .eslintrc파일을 만들어주자. 알아서 json 확장자로 인식한다. 이후 다음과 같이 붙여넣어주면 된다. 물론 커스터마이징은 다음 사이트를 참고해 알아서 하면 된다. rules에 규칙을 추가하거나 extension을 추가하는 등!
https://eslint.org/docs/latest/rules/

참고로 error를 warn으로 변경하면 에러 대신 경고를 띄워주서 좀 더 숨통 트인 채로 개발이 가능하긴 하다. 하지만 팀원들끼리 error로 맞춰놨다면 꼭 github에 올리기 전에 warn으로 바꿔주자.

{
  "extends": ["react-app", "eslint:recommended"], // eslint에서 기본적으로 추천하는 것을 사용하되, rules에 있는 것들을 추가적으로 적용
  "rules": {
    "no-var": "error", // var 금지
    "no-multiple-empty-lines": "error", // 여러 줄 공백 금지
    "no-console": ["error", { "allow": ["warn", "error", "info"] }], // console.log() 금지
    "eqeqeq": "error", // 일치 연산자 사용 필수
    "dot-notation": "error", // 가능하다면 dot notation 사용
    "no-unused-vars": "error" // 사용하지 않는 변수 금지
		"react/jsx-no-useless-fragment": "error"
  }
}

Prettier

마찬가지로 프로젝트의 루트 디렉토리에 .prettierrc 파일을 만든다. 그리고 다음과 같이 설정해준다. 다음 사이트를 참고해 마찬가지로 규칙을 커스터마이징 해주면 된다.
https://prettier.io/docs/en/options.html

{
  "arrowParens": "always",
  "bracketSpacing": true,
  "htmlWhitespaceSensitivity": "css",
  "insertPragma": false,
  "bracketSameLine": false,
  "jsxSingleQuote": false,
  "printWidth": 80,
  "proseWrap": "preserve",
  "quoteProps": "as-needed",
  "semi": true,
  "singleQuote": true,
  "useTabs": false,
  "tabWidth": 2,
  "trailingComma": "all",
  "endOfLine": "lf"
}

이렇게 하면 이제 저장 시 이 룰대로 포맷팅 되는 것을 확인할 수 있다.

Husky

npx husky install을 입력해주자. 그러면 husky 폴더가 추가되는데, 여기에 우리가 설정하는 git hook들이 추가된다.

그리고 package.json 파일의 scripts에서 다음과 같이 추가해주자.

{
  "scripts": {
    "postinstall": "husky install"
		"format": "prettier --cache --write .",
		"lint": "eslint --cache .",
  },
}

여기서 postinstall은, 팀원이 npm install을 하면 알아서 husky install을 실행시키겠다는 것이다. husky가 깔리도록 하는 것.

npx husky add .husky/pre-commit "npm run format"npx husky add .husky/pre-push "npm run lint"를 터미널에 입력해주자. commit 하기 전에 npm run format, 즉 prettier --cache --write .와 push 하기 전에 npm run lint, 즉 eslint --cache .를 실행시켜 각각 prettier와 eslint가 작동하도록 하겠다는 것이다. 작동하면서 에러가 발생한다면 git commit 혹은 git push가 제대로 안될 것이고, 다시 말하면 prettier 혹은 eslint가 제대로 적용 안된 코드로 인해 에러가 발생하면서 잘못된 코드가 올라가는 것을 방지할 수 있게 된다.

  • prettier --cache --write .에서 .은 .prettierrc 파일 하위의 모든 파일에 적용하겠다는 것이다. eslint도 마찬가지.
    • write는 prettier를 돌리고 저장까지 해주는 것이다.
    • 모든 파일을 다 돌면서 prettier, eslint를 적용하는 것은 비효율적이다. cache에 파일 상태를 저장해뒀다가, 코드 작성 후 나중에 prettier, eslint가 동작할 때 cache와 현재 파일 상태를 대조해 바뀐 파일만 prettier 혹은 eslint가 동작하게 할 수 있다.

결론

위와 같이 하면 끝난다. 설명을 함께하다보니 두서 없이 써놨는데, 다음과 같은 순서를 걸치면 된다.
npm install prettier --save-dev
npm install eslint-config-prettier --save-dev
npm install husky --save-dev
.eslintrc, .prettierrc 파일을 프로젝트의 루트 디렉토리에 생성 후 각각 위 설명의 설정대로 기입.
npx husky install
npx husky add .husky/pre-commit "npm run format"
npx husky add .husky/pre-push "npm run lint"
끄읏

깃헙 레파지토리 판 후 레파지토리 주소 따와서 git remote add origin 레파지토리주소 하고, 다음과 같이 commmit, push을 하면 각각 prettier와 eslint가 작용하는 것을 볼 수 있다.

당연히 var를 쓰는 등 eslint를 어기거나, 작은 따옴표로 작성하기로 했는데 큰 따옴표를 썼으면 해당 과정에서 에러를 띄우거나 보정을 해준다.

var 썼다고 다시 쓰란다.








통일된 컨벤션을 위해 어떻게 강제할 수 있는지 알아보았다. 다음 팀 프로젝트를 진행하게 되면, 아니면 나 혼자 진행하더라도 꼭 적용해봐야겠다.




profile
메타몽 닮음 :) email: alohajune22@gmail.com

0개의 댓글