정말 리얼 마지막 ESLint 사용법 뿌시기

🌊·2023년 4월 27일
2

Lint

목록 보기
1/4
post-thumbnail

오늘은 eslint에 대해서.. 정말 마지막으로 ESLint에 대해서 뿌셔보려고 합니다..!

그래도 이전에 @typescript-eslintstyleslint 등을 사용하면서 eslint를 그래도 잘 사용하고 있다고 생각하고 있었는데요!
매번 사용을 할 때마다 계속 헷갈려하는 제 모습을 보고.. 이해를 못하고 있다고 생각이 들었습니다.

매번 적용을 하다보면 궁금해 하는 질문은 공통적이었습니다.
1. eslint-configeslint-plugin의 제대로 된 차이점은 무엇인가?
2. extends, rule, recommended는 어떻게 해석하는가?
3. .eslintrc.js 파일은 어떤 방식으로 작성해야 하는가?

이렇게 적고보니.. 그냥 아예 lint를 모르는 사람 같았습니다.. 🤦‍♂️
그래서 오늘은 다시 한 번 정리와 함께 더 이상의 이론은 공부하지 않겠다는 다짐으로 작성해보려고 합니다.

eslint란?

  • 자바스크립트 코드에서 문제를 찾아주고 고쳐주는 정적 분석 도구
  • 기본적으로 CRA로 리액트 프로젝트를 생성하게 되면 eslint-config-react-app이라는 설정이 세팅되어 있다.

정적 분석 도구... 정말 많이 들었던 것 같습니다.. ㅎ
그리고 CRA 과정에서 eslint 관련된 라이브러리가 설치 된다는 것을 처음 알았습니다.

pluginconfig

사실 eslint를 사용하면서 가장 구분이 잘 되지 않고, 제대로 이해하기 어려웠던 부분이었습니다.

예를 들면 eslint-plugin-import, eslint-config-prettier, eslint-plugin-prettier 이런식으로 점점 추가해서 사용하라고 이야기하는데.. 추가하면 할수록 뭐가 뭔지 점점 헷갈리게 됩니다.

오늘은 확실하게 구분지어서 개념을 정리해보겠습니다. 🪓

eslint-plugin-*

짧게 플러그인이라고 하겠습니다.

플러그인 패키지는 룰을 정리한 패키지입니다.
예를 들면 eslint-plugin-react라는 패키지는 리액트와 관련된 룰을 정의한 패키지입니다.

그렇다면 사용은 어떻게 할까요?

{
	"plugins": ["react"]
}

eslint 설정을 할 때 흔히 보던 명칭입니다.
하지만 이렇게 작성하면 아무런 동작을 하지 않습니다.. 🤯
위의 의미는 "나는 이제 eslint-plugin-react를 추가할거야!" 라고 하는 것과 동일합니다.

선언만하고 사용은 하지 않은 것이죠..
그러면 해당 패키지를 사용하려면 어떻게 해야할까요?
rules에서 관리를 해줘야 합니다.

{
	"plugins": ["react"],
	"rules": {
		"react/jsx-uses-react": error
	}
}

이런식으로 해당 플러그인에 대한 룰(규칙)을 직접 입력해서 사용할 수 있습니다.

하지만 이렇게 플러그인을 사용하려면 매번 모든 플러그인의 룰을 알고 있어야하고, 활용할 줄 알아야합니다.
그리고 사용할 모든 룰을 직접 작성해줘야 합니다.

하나의 플러그인만 사용한다면 모를까 대부분의 사람들은 여러 플러그인을 설치해서 사용합니다.
사실상 모든 룰을 다 숙지한다는 것은 매우 어렵습니다.

그렇기 때문에 대부분의 플러그인은 자체 설정을 제공합니다.
그 자체 설정이 recommended, strict, all 과 같은 단어입니다.

해당 플러그인에서 제공하는 자체 설정을 사용하려면

{
	"extends": ["plugin:react/recommended"]
}

위와 같은 코드로 작성해줘야 합니다.
흔히 보던 recommended라는 키워드가 나왔습니다.

그렇다면 여기서 궁금증이 생길 수 있습니다.

자체 설정은 뭐고.. 좀전에 플러그인은 plugins 안에서 사용한다고 했는데.. 왜 extends라는 영역에서 사용하는거지? 🤔

자체 설정은 플러그인에서 룰에 대한 세팅을 해놓고 제공하는 것을 의미합니다.
그리고 해당 플러그인에서 제공하는 자체 설정의 경우에는 extends 영역에서 사용해야 합니다.
(하지만 왜 extends 영역에서 사용해야 되는지는.. 잘모르겠습니다.. 🥲)

// eslint-plugin-react/configs/recommended
'use strict';

const all = require('./all');

module.exports = Object.assign({}, all, {
  languageOptions: all.languageOptions,
  rules: {
    'react/display-name': 2,
    'react/jsx-key': 2,
    'react/jsx-no-comment-textnodes': 2,
    'react/jsx-no-duplicate-props': 2,
    'react/jsx-no-target-blank': 2,
    'react/jsx-no-undef': 2,
    'react/jsx-uses-react': 2,
    'react/jsx-uses-vars': 2,
    'react/no-children-prop': 2,
    'react/no-danger-with-children': 2,
    'react/no-deprecated': 2,
    'react/no-direct-mutation-state': 2,
    'react/no-find-dom-node': 2,
    'react/no-is-mounted': 2,
    'react/no-render-return-value': 2,
    'react/no-string-refs': 2,
    'react/no-unescaped-entities': 2,
    'react/no-unknown-property': 2,
    'react/no-unsafe': 0,
    'react/prop-types': 2,
    'react/react-in-jsx-scope': 2,
    'react/require-render-return': 2,
  },
});

// this is so the `languageOptions` property won't be warned in the new config system
Object.defineProperty(module.exports, 'languageOptions', { enumerable: false });

위와같이 recommended 설정에는 직접 입력해야하는 룰들이 이미 입력이 되어있습니다.
그리고 이미 플러그인을 포함하고 있습니다.

하지만 plugins이 안 보이실겁니다..!
그 이유는 all 자체 설정에서 플러그인을 포함하고 있고 해당 설정을 불러와서 다시 로직을 처리하기 때문에 plugins 영역을 recommended 설정에서 찾을 수 없습니다!

위의 코드를 보면 all config 설정을 불러와서 Object.assign() 함수를 통해서 recommended config 설정을 하는 모습을 볼 수 있습니다.

eslint-config-*

그렇다면 config 패키지는 무엇일까요? 😁

eslint-plugin 패키지들이나 룰들을 모아서 설정으로 만든 것이 eslint-config-* 패키지입니다.

eslint에 관심이 있으시다면 많은 분들이 보셨던 eslint-config-airbnb 패키지를 예를 들 수 있습니다.
eslint-config-airbnb 패키지 내부에는 아래의 플러그인과 룰들을 조합해서 만든 설정 패키지입니다.

  • eslint
  • eslint-plugin-import
  • eslint-plugin-react
  • eslint-plugin-react-hooks
  • eslint-plugin-jsx-a11y
{
	"extends": ["airbnb"]
}

사용할 때는 위와 같이 간단하게 사용할 수 있습니다.

parser

대부분 저처럼 eslint-plugin이나 eslint-config에 빠져서 지나치는 경우가 있습니다.

parser는 무엇일까요?
코드를 분석하기 위한 파싱 툴입니다.
기본 값은 espree 입니다. 오늘은 parser에 대해서는 자세하게 다루지는 않으려고 합니다..!

보통 자바스크립트에서는 @babel/eslint-parser를 사용합니다.
타입스크립트에서는 @typescript-eslint/parser를 사용합니다.

이번에 알게 된 사실인데 아래처럼 recommended 자체 설정을 사용하게 되면 @typescript-eslint/parser가 자동적으로 포함됩니다..!

{
	extends: ["plugin:@typescript-eslint/recommended"]
}
// typescript-eslint/packages/eslint-plugin/src/config/base.ts

export = {
  parser: '@typescript-eslint/parser',
  parserOptions: { sourceType: 'module' },
  plugins: ['@typescript-eslint'],
};

순간 @typescript-eslint조차도 plugin이라고 생각했던.. 저를 반성하며.. 🤦‍♂️
@typescript-eslintparser도 있고 플러그인도 있고, 자체 설정도 포함되어 있었던 것이죠.. ㅎ

정리

eslint-plugin

  • eslint에 대한 룰만 정의한 패키지이다. (아직 사용한다고 말 안했다.)
  • eslint 설정 파일의 plugins, extends 영역에서 사용 가능하다.
  • 기본적으로 커스텀한 규칙을 모아서 제공하기 위해 만들어진다.
  • 자체 설정(config)을 사용하지 않는다면 개인적으로 룰을 숙지하고 설정해줘야 한다.
  • 자체 설정은 extends 영역에서 plugin:패키지이름/config이름으로 사용해야 한다.
  • 자체 설정은 어떤 룰을 사용할 것인지도 설정이 되어 있고, 이미 eslint-plugin도 포함되어 있다.
  • 네이밍은 기본적으로 eslint-plugin-*, @<scope>/eslint-plugin, @<scope>/eslint-plugin-* 식으로 사용할 수 있다.
  • 플러그인의 환경 설정, 플러그인의 프로세서, 복수 개의 config를 포함할 수 있다.

eslint-config

  • eslint-plugin 패키지들과 룰을 모아서 설정으로 만든 패키지이다.
  • 일반적으로 eslint 설정 파일들을 공유하기 위한 목적으로 만들어진다.
  • eslint 설정 파일의 extends 영역에서 사용해야 한다.
  • 플러그인의 경우에는 자체 설정을 사용하려면 extends 영역에서 plugin:패키지이름/config이름으로 사용해야 하는데 eslint-config는 패키지 이름만 써주면 된다.
  • 네이밍은 기본적으로 eslint-config-*, @<scope>/eslint-config, @<scope>/eslint-config-* 식으로 사용할 수 있다.

자신만의 규칙도 만들고 설정도 만들고 싶다면 eslint-plugin을 사용하거나 만드는 것을 추천합니다. 하지만 airbnb처럼 기존의 설정들을 모아서 공유하려는 목적이 강하다면 eslint-config를 사용하거나 만드는 것을 추천합니다.

마무리

다양한 eslint-plugin이나 eslint-config 패키지들에 관심을 가지면서 이렇게 정리를 해보게 되었습니다.
알고 쓰는 것과 모르고 쓰는 것의 차이는 크다고 생각합니다.
앞으로는 과거보다는 더 잘 알고 쓴다는 생각에 조금 더 뿌듯하긴 합니다. 😎

그리고 사용하다보니 불편한 점도 있었고, 커스텀해보고 싶다는 생각도 들었습니다.

시간이 될 때 개인적으로 eslint-plugin, eslint-config 패키지 하나씩 만들어 보려고 합니다.
개인적으로 프로젝트 만들때마다 설정하는 것도 귀찮기도하고.. 회사에서 협업용으로 하나 만들어서 가져가보려고 합니다!

출처

0개의 댓글