ESLint 자동화하기

Juhwan Lee·2022년 8월 28일
2
post-thumbnail

그저께 4년차 프론트엔드 개발을 하고있는 지인과 술자리를 함께하며 이러 저러한 얘기를 많이 나누었는데, 원래 남이 작성한 코드 뜯어 고치는게 난이도가 상당한 편이란다.

가끔 충동이 몰려오긴 하는데,

모든 순간을 성장의 발판으로 삼아야겠고,
지금 힘든 것 또한 내가 부족해서라 생각한다.

사건의 발단

회사의 package.json 파일을 보며, 사용 중인 packgage들을 뜯어보고 있는데 lint 설정에 관한 패키지가 다수 있었다.

  • @typescript-eslint/parser
  • eslint-plugin-import
  • eslint-plugin-react-hooks
  • eslint-plugin-simple-import-sort
  • lint-staged

공통적으로 eslint-plugin-*이란 룰을 정의한 것으로
.eslintrc.json 파일에 plugin을 추가해주면 된다. 단순히 plugins에 추가하는 것 만으로는 동작이 일어나지 않고, rules를 정의해주어야 동작을 한다.

  • 아래는 기본적으로 project에 정리되어 있던 .eslintrc.json 파일이다.
{
  "parserOptions": {
    "sourceType": "module"
  },
  "parser": "@typescript-eslint/parser",
  "plugins": ["react-hooks", "simple-import-sort", "import"],
  "rules": {
    "react-hooks/rules-of-hooks": "error",
    "react-hooks/exhaustive-deps": "error",
    "simple-import-sort/imports": "error",
    "simple-import-sort/exports": "error"
  }
}

@typescript-eslint/parser는 코드를 분석하기 위한 파싱툴이고, 기본값은 espree이다. typescript 워크스페이스에서는 보통 @typescript-eslint/parser를 사용하기에 설정해준 것으로 보인다.

여기서 살짝 의문이 드는 게 eslint-plugin-import를 추가해주었지만, 다른 룰은 적용하지 않아 있다.

그리고 룰을 어겼을 때, error만 반환할 뿐 autofix는 적용되지 않는 불편함을 발견했다.
(이부분은 lint를 돌렸을 때 자동으로 수정되게 바꾸었다)

eslint-plugin-import는 ES2015+ import/export 구문의 린팅과 이슈를 방지해주는 플러그인이라고 나와있으며,
eslint-plugin-simple-import-sort는 좋은 기본값을 사용하여 정렬할 수 있을 뿐만 아니라 정의된 패턴에 따라 그룹을 나눌 수 있는 플러그인이라고 한다.

eslint-plugin-import을 좀 더 잘 활용하기 위해

{
  "rules": {
    ...
    "import/first": "error",
    "import/newline-after-import": "error",
    "import/no-duplicates": "error"
  }
}

을 추가해 주었으며,simple-import-sort/imports rule에 조건을 더 추가했다.

...
    "simple-import-sort/imports": [
      "error",
      {
        "groups": [
          // Packages `react` related packages come first.
          ["^react", "^@?\\w"],
          // Internal packages.
          ["^(@|components)(/.*|$)"],
          // Side effect imports.
          ["^\\u0000"],
          // Parent imports. Put `..` last.
          ["^\\.\\.(?!/?$)", "^\\.\\./?$"],
          // Other relative imports. Put same-folder imports and `.` last.
          ["^\\./(?=.*/)(?!/?$)", "^\\.(?!/?$)", "^\\./?$"],
          // Style imports.
          ["^.+\\.?(css)$"]
        ]
      }
    ],
...

package.json 파일에 lint 명령어 또한 추가해주었다.

"script" : {
  ...
  "lint": "eslint \"./src/**/*.{ts,tsx}\" --fix",
}

eslint와 prettier를 통합해주기 위하여, eslint-config-prettier, eslint-plugin-prettier을 설치한 뒤

npm i -D eslint-config-prettier eslint-plugin-prettier

eslintrc.json 파일에 추가 해주었다.

  ...
  "extends": ["plugin:prettier/recommended"]
  ...

husky와 lint-staged 사용하기

앞서 기본적인 lint를 설정해주었으며, ESLint를 자동화해주기 위해, husky와 lint-staged를 결합해 사용하기로 하였다.

(기존에 lint-staged라는 패키지가 설치 되어있었는데, 더욱더 효과적인 사용을 위하여 husky를 추가적으로 사용하기로 했다.)

npx mrm lint-staged

mrm이란 오픈소스 프로젝트 환경 설정을 동기화 하기 위한 도구인데, 간편한 husky 설정을 위해 사용하였다.

앞으로 commit이 될 떄 staged된 파일들이 lint와 prettier 설정과 일치하는지 검사를 하게될 예정이다.

마치며

아직 부족한 부분이 많을지라도 하나하나 공부해가며 맞춰보고 적용해 나갈 예정이다.
솔직한 마음으로 router 처리나 폴더구조까지 싹 바꾸고 싶지만 현실적으로 시간이 모자라기 때문에 feature를 늘려가면서 조금씩 리팩토링도 곁들여야겠다.
atomic으로 view 컴포넌트도 다 빼고 싶은데.. 시간이 될지 모르겠다.

🛠추가사항

windows 11에서 작업을 하고 혹시나 하는 마음에 맥북으로 받아와 적용이 제대로 되는지 확인을 해보았는데, The '.husky/pre-commit' hook was ignored because it's not set as executable.
라는 메세지가 뜨며 lint 오류가 있음에도 커밋이 되는 문제가 있었다.

해당 문제에 대한 github issue

chmod ug+x .husky/*

명령어를 사용 후 origin에 push하여 문제를 해결 하였으나,
issue 답변 중에 chmod를 사용한 방법은 일반적인 해결 방법이 아니라는 의견이 있어서 지켜봐야겠다.

profile
keep going

0개의 댓글