ABOUT ME

-

Today
-
Total
-
  • ESLint를 자동화해보자 (feat. husky & lint-staged)
    Study/Frontend 2022. 4. 14. 13:23
    반응형

     

    Lint

    코드의 오류나 버그, 스타일 등을 점검하는 것을 lint라고 부른다. 린트는 코드의 가독성을 높이는 것뿐만 아니라 자바스크립트와 같은 동적 언어의 특성인 런타임 버그를 예방하는 역할도 한다.

    ESLint는 ECMAScript 코드에서 문제점을 검사하고 더 나은 코드로 고쳐주는 lint tool이다. ESLint를 사용해서 개발을 하면 잠재적인 오류와 버그를 제거할 수 있다.

    협업을 하는 프로젝트에서 lint를 적용하는 것은 필수라고 할 수 있다. 왜냐하면 모든 개발자들이 같은 규칙 내에서 개발해야 잠재적인 오류를 방지할 수 있기 때문이다.

     

    하지만,

    아무리 ESLint를 모든 개발자들이 사용한다고 해도 warning, error 등 lint 결과를 무시하고 바로 commit 하고 push 해버릴 수도 있다.

    이러한 상황을 미연에 방지하기 위해서는 lint 에러가 있는 경우 commit을 하지 못하도록 하는 것이 최선의 방법일 것이다. 이를 구현하기 위해서는 git hook이라는 것을 사용하면 된다.

     

    Git Hook

    프로그래밍에서 hook이란 특정 이벤트 또는 함수가 호출되기 전/후에 호출이 되는 코드를 의미한다.

    Git은 특정 상황에 특정 스크립트를 실행할 수 있도록 하는 Hook이라는 기능을 지원하고 있다. 별도로 설치할 것은 없고 모든 git repository에서 지원한다. git으로 관리하고 있는 폴더에서 cd .git/hooks/ 명령어를 치고 ls 명령어를 쳐보면 .sample 확장자로 되어있는 파일이 13개가 있다. 이는 git hook이 지원하는 특정 상황이 13개인 것을 알 수 있다. 해당 hook을 사용하려면 .sample 확장자만 지우면 된다.

    이번에 사용해볼 git hook은 pre-commit이다.

    pre-commit은 단어 뜻 그대로 commit 직전에 실행되는 hook이다.

     

    husky

    git hooks는 .git 디렉터리에 저장되기 때문에 git repository에 원격으로 저장하고 관리할 수 없다. 따라서 git hook을 공유하기 위한 방법에는 여러 가지가 있지만 그중 husky를 사용해보고자 한다.

    husky란 Node.js 개발 환경에서 git hook을 편리하게 사용할 수 있게 만들어주는 도구이다. husky를 사용하면 프로젝트 별로 commit, push 등과 관련된 정책을 관리하고 공유할 수 있다.

     

    lint-staged

    git hook을 활용해서 commit 하기 전에 lint를 실행해서 코드를 검사할 수 있게 됐다. 하지만 검사해야하는 확장자에 해당하는 모든 파일을 검사하려면 굉장히 오랜 시간이 소요될 것이다. 이때 lint-staged를 함께 사용하면 변경된 파일만 검사할 수 있다. 즉 git staging area에 올라온 파일만 검사할 수 있다

     

     


     

     

    지금부터 React 프로젝트에서 husky와 lint-staged를 활용해서 commit 전에 ESLint를 자동화해보도록 하겠다.

     

    1. 모듈 설치 : npm install husky lint-staged

    모듈을 설치하기 전에 ESLint, Prettier 등 도구를 설치 및 세팅해놔야 한다.

    설치가 완료되면 .husky 폴더가 루트에 생긴다. 

     그리고 package.json 파일에 아래와 같은 코드를 추가하고 해당 스크립트를 한 번 실행한다.

    "scripts": {
      "prepare": "husky install"
    }

    Yarn2를 사용하고 있다면 아래와 같이 코드를 추가하고 해당 스크립트를 한 번 실행한다.

    "scripts": {
      "postinstall": "husky install"
    }

     

    실행 후 .husky 폴더의 pre-commit 파일을 살펴보면 npx lint-staged라는 명령어가 있는데, commit 전에 이 명령어를 실행한다는 의미이다.

    #!/bin/sh
    . "$(dirname "$0")/_/husky.sh"
    
    npx lint-staged

     

    2. package.json의 lint-staged 설정

    ESLint를 실행하여 검사하고 싶은 확장자를 설정하고 원하는 옵션도 세팅해서 명령어를 작성하면 된다.

    나는 아래와 같이 ESLint의 cache, fix 옵션을 설정했다.

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

     

    3. git add , git commit 실행

    코드를 수정하고 git add를 한 후에 git commit을 하면 우리가 세팅한 husky와 lint-staged에 의해 ESLint가 실행된다.

    lint 에러가 있다면 commit에 실패하고 어떤 에러가 발생했는지 터미널에 나타난다.

     

    lint 에러를 고치고 다시 commit을 실행하면 정상적으로 commit이 되는 것을 볼 수 있다.

     

     

     

    ESLint를 자동화해보며..

    git hook을 사용해서 ESLint를 자동화하는 과정을 알아봤다.

    이처럼 lint에 사용해도 되고 master 브랜치에 직접 push 하는 것을 막을 수도 있고 git hook은 다양한 정책에 활용할 수 있다.

    필요한 정책을 셋업하고 유연하게 각자 프로젝트에 적용해보자!

     

     

     


    22년 6월 9일 추가 내용

    Next.js 프로젝트 적용 방법

     

    package.json

    {
      "name": "next",
      "version": "0.1.0",
      "private": true,
      "scripts": {
        "dev": "next dev",
        "build": "next build",
        "start": "next start",
        "lint": "next lint --fix",
        "prepare": "husky install"
      },
      "dependencies": {
        "next": "12.1.6",
        "react": "18.1.0",
        "react-dom": "18.1.0"
      },
      "devDependencies": {
        "@types/node": "17.0.40",
        "@types/react": "18.0.12",
        "@types/react-dom": "18.0.5",
        "@typescript-eslint/eslint-plugin": "^5.27.1",
        "eslint": "8.17.0",
        "eslint-config-next": "12.1.6",
        "eslint-config-prettier": "^8.5.0",
        "husky": ">=6",
        "lint-staged": ">=10",
        "prettier": "^2.6.2",
        "typescript": "4.7.3"
      },
      "lint-staged": {
        "*.{ts,tsx}": "next lint --fix"
      }
    }

     

    create-next-app으로 프로젝트를 셋업 했을 때 기본적으로 eslint가 세팅되어있고, lint 실행은 next lint로 가능하다.

    React 프로젝트와 비교했을 때 husky, lint-staged를 사용하는 방법은 크게 다르지 않은데, 중요한 한 가지가 있다.

    바로 .lintstagedrc.js 파일을 생성해야 한다는 것이다.

    Next.js 프로젝트 루트 폴더에 파일을 생성하고 공식 문서에서 제공해준 아래와 같은 코드를 작성해주면 된다.

     

    .lintstagedrc.js

    const path = require('path')
    
    const buildEslintCommand = (filenames) =>
      `next lint --fix --file ${filenames
        .map((f) => path.relative(process.cwd(), f))
        .join(' --file ')}`
    
    module.exports = {
      '*.{js,jsx,ts,tsx}': [buildEslintCommand],
    }

     

     .lintstagedrc.js 파일을 생성하지 않으면 에러가 나면서 린트가 실행되지 않으므로 반드시 위와 같은 작업을 진행해주자!

     

     

     

     

     

     

    참고 문헌

    https://github.com/okonet/lint-staged

    https://typicode.github.io/husky/#/

    https://library.gabia.com/contents/8492/

    https://techblog.woowahan.com/2530/

    https://nextjs.org/docs/basic-features/eslint#lint-staged

    반응형

    댓글