(1) ESLint와 Prettier가 무엇이며 왜 필요하고 어떻게 사용하는지

남주영·2022년 4월 24일
36

해당 글은 시리즈로 작성될 예정입니다! React 프로젝트에서 일관성 있는 코드를 유지하기 위해 사용하는 ESLint, Prettier, husky, lint-staged가 무엇인지, 왜 사용하며, 어떻게 사용하는지 알아볼 것이며 아래 순서로 포스팅 될 것입니다. :)
> (1) ESLint와 Prettier가 무엇이며 왜 필요하고 어떻게 사용하는지
(2) 기본적인 ESLint, Prettier config
(3) husky와 lint-staged로 커밋할 때마다 자동으로 lint 검사하기

ESLintPrettier는 일정한 규칙에 맞는 코드 퀄리티 및 스타일을 유지할 수 있게 검사해주는 도구이며,
huskylint-staged는 그 검사에 통과되지 않은 파일을 git에 commit할 수 없도록 하기 위해 사용한다.

이번 글에서는 ESLint와 Prettier에 대해 알아보겠다.

ESLint와 Prettier

ESLint란?

자바스크립트 코드에서 발견된 문제 패턴을 식별하기 위한 정적 코드 분석 도구이다.
대부분의 프로그래밍 언어에는 컴파일하는 과정에서 수행되는 Linter가 기본적으로 내장되어 있다.
그러나, 인터프리터 언어인 자바스크립트는 Linter가 내장되어 있지 않다.
이 때문에 런타임 환경에서 에러가 발생할 확률이 높다.

따라서 ESLint와 같은 Linting 도구를 사용한다.

Lint란?
소스코드를 분석하여 문법적인 오류나 스타일적인 오류, 적절하지 않은 구조 등에 표시를 달아주는 행위이며, Linter란 Lint의 동작을 도와주는 도구를 말한다.

자바스크립트로 특정 기능을 구현할 때, 그 기능을 구현하기 위해 굉장히 다양한 방식을 사용할 수 있다.

함수를 선언하는 데에도 크게 4가지 방식이 있고, 배열을 순회하기 위해서도 굉장히 다양한 방법을 사용할 수 있다.

// 함수 선언문
function square(number) {
  return number * number;
}

// 기명 함수 표현식(named function expression)
const foo = function multiply(a, b) {
  return a * b;
};

// 익명 함수 표현식(anonymous function expression)
const bar = function(a, b) {
  return a * b;
};

// 생성자 함수
const square = new Function('number', 'return number * number');
console.log(square(10)); // 100

// 화살표 함수
// 매개변수 지정 방법
    () => { ... } // 매개변수가 없을 경우
     x => { ... } // 매개변수가 한 개인 경우, 소괄호를 생략할 수 있다.
(x, y) => { ... } // 매개변수가 여러 개인 경우, 소괄호를 생략할 수 없다.

// 함수 몸체 지정 방법
x => { return x * x }  // single line block
x => x * x             // 함수 몸체가 한줄의 구문이라면 중괄호를 생략할 수 있으며 암묵적으로 return된다. 위 표현과 동일하다.

() => { return { a: 1 }; }
() => ({ a: 1 })  // 위 표현과 동일하다. 객체 반환시 소괄호를 사용한다.

() => {           // multi line block.
  const x = 10;
  return x * x;
};
const arr = [0, 1, 2, 3];
arr.foo = 10;

for (const key in arr) {
  console.log('key: ' + key, 'value: ' + arr[key]);
}

arr.forEach((item, index) => console.log(index, item));

for (let i = 0; i < arr.length; i++) {
  console.log(i, arr[i]);
}

for (const item of arr) {
  console.log(item);
}

이처럼 다양한 방식으로 구현할 수 있는 코드 방식을 일관성 있게 구현할 수 있도록 잡아주는 것이 ESLint가 하는 역할이다.

(이 예시는 극히 일부이며 다양한 플러그인을 통해 자바스크립트를 넘어서 React/React Hooks/TypeScript 등 자바스크립트를 기반으로 한 다양한 환경에서의 코드 규칙을 설정할 수 있다!)

Prettier란?

깔끔한 코드와 협업을 위해선 일관성 있는 코드 스타일을 유지하는 것이 매우 중요하다.
ESLint가 코드 퀄리티를 일관적으로 유지해준다면,
Prettier는 일관적인 코드 스타일을 유지할 수 있게 도와주는 툴이다.
다시 말해 ESLint는 문법 에러를 잡아주거나 더 좋은 코드 구현 방식을 사용하도록 해주지만, Prettier는 줄 바꿈, 공백, 들여 쓰기 등과 같은 스타일을 교정해준다.

예를 들어 아래와 같은 코드를

function HelloWorld({greeting = "hello", greeted = '"World"', silent = false, onMouseOver,}) {

  if(!greeting){return null};

     // TODO: Don't use random in render
  let num = Math.floor (Math.random() * 1E+7).toString().replace(/\.\d+/ig, "")

  return <div className='HelloWorld' title={`You are visitor number ${ num }`} onMouseOver={onMouseOver}>

    <strong>{ greeting.slice( 0, 1 ).toUpperCase() + greeting.slice(1).toLowerCase() }</strong>
    {greeting.endsWith(",") ? " " : <span style={{color: '\grey'}}>", "</span> }
    <em>
	{ greeted }
	</em>
    { (silent)
      ? "."
      : "!"}

    </div>;

}

아래와 같이 잡아줄 수 있다.

function HelloWorld({
  greeting = "hello",
  greeted = '"World"',
  silent = false,
  onMouseOver,
}) {
  if (!greeting) {
    return null;
  }

  // TODO: Don't use random in render
  let num = Math.floor(Math.random() * 1e7)
    .toString()
    .replace(/\.\d+/gi, "");

  return (
    <div
      className="HelloWorld"
      title={`You are visitor number ${num}`}
      onMouseOver={onMouseOver}
    >
      <strong>
        {greeting.slice(0, 1).toUpperCase() + greeting.slice(1).toLowerCase()}
      </strong>
      {greeting.endsWith(",") ? (
        " "
      ) : (
        <span style={{ color: "grey" }}>", "</span>
      )}
      <em>{greeted}</em>
      {silent ? "." : "!"}
    </div>
  );
}

사용하는 방법

환경은 vscode, CRA, typescript, yarn 전제로 설명하겠다.

둘 다 패키지 설치, vscode extension 설치가 필요하며 각각의 설정 파일을 통해 원하는 코드 구현 방식, 스타일 등을 vscode 상에서 경고/에러 표기를 강제하도록 할 수 있다.
또한 vscode 설정을 통해 가능한 것은 저장할 때마다 강제 수정이 되도록 할 수 있다.

ESLint 설치

yarn add -D eslint

-D 옵션으로 설치하는 이유
package.json에 개발 시에만 사용하는 개발 의존성(devDependencies)으로 기록되게 된다. 개발 의존성으로 설치된 패키지는 --production 옵션을 통해 운영 버전에서는 설치되지 않게 할 수 있다.

vscode extension 설치

.eslintrc 설정

각종 lint 룰 설정을 위해서는 프로젝트 루트 디렉토리에 .eslintrc 파일을 만들어서 작성해줘야 한다.
.eslintrc 파일의 확장자는 js, json, yml로 다양하게 설정할 수 있는데 이 글에서는 json으로 하겠다.

.eslintrc 파일의 구성을 살펴보겠다.
아래는 ESLint 공식 문서의 예시이다.

ESLint 공식 문서의 이 글을 읽어보면 아주 상세히 설명되어 있으니 이 곳을 참고해도 좋다.

{
    "root": true,
    "extends": [
        "eslint:recommended",
        "plugin:@typescript-eslint/recommended"
    ],
    "parser": "@typescript-eslint/parser",
    "parserOptions": { "project": ["./tsconfig.json"] },
    "plugins": [
        "@typescript-eslint"
    ],
    "rules": {
        "@typescript-eslint/strict-boolean-expressions": [
            2,
            {
                "allowString" : false,
                "allowNumber" : false
            }
        ]
    },
    "ignorePatterns": ["src/**/*.test.ts", "src/frontend/generated/*"]
}

lint 설정을 위해 중요한 부분은 plugins, extends, rules인데 다른 부분도 알아두면 좋다.

  • root
    default가 true이며, 이 값이 true가 아니면 eslintrc 파일을 찾을 때 상위의 디렉토리까지 검색하게 된다.
  • plugins
    • plugin 설정을 통해 다른 사람이 만든 규칙을 가지고 올 수 있다.
    • plugin의 종류는 다양하며 여러 plugin을 가져와서 사용하는 경우가 많다. 많이 사용하는 기본적은 plugin으로는 ESLint에서 기본적으로 제공하는 plugin이 있으며, react/react hooks/typescript를 위한 plugin도 있다. 또, 에어비앤비 lint plugin도 많이 사용한다.
    • plugins에 추가된다고 해서 바로 적용되는 것은 아니다. 그저 가지고 오겠다는 것이며 extendsrules 설정을 해야 적용을 할 수 있다.
  • extends
    • plugin package의 규칙을 그대로 따르고 싶을 때 plugin을 extends에 추가해준다.
    • 가져온 plugin을 일부만 사용할 수 있지만 보통 extends를 통해 plugin을 통째로 가져와 사용한다.
    • plugin에서 extends 옵션을 제공하는 경우가 많은데, recommended/strict/all 등이 있다. plugin의 규칙을 얼마나 어떻게 따를 것인지를 의미하며 보통 recommened를 많이 사용한다.
       "extends": [
          "eslint:recommended",
          "plugin:@typescript-eslint/recommended"
      ],
  • parser
    • ESLint가 구문 분석을 위해 어떤 parser를 사용할지 설정해주는 것이다.
    • 기본적으로는 Espree 파서를 사용하는데, TypeScirpt 구문 분석을 위해서는 @typescript-eslint/parser를 사용하며 설치가 필요하다.
      yarn add -D @typescript-eslint/parser
  • rules
    • plugin의 규칙을 커스텀할 수 있는 곳이다. extends 하여 기본으로 설정된 규칙을 바꾸거나 없앨 수 있고, 기본으로 설정되지 않은 규칙을 추가할 수도 있다. (ex typescript-eslint plugin을 recommended로 extends한 후, recommended에 포함되어 있는 no-explicit-any를 없앨 수 있고 recommended에 포함되어 있지 않은 consistent-type-definitions를 설정해줄 수도 있다.)

이 외에도parserOptions, env 등을 설정해줄 수 있다.

  • parserOptions
    "parserOptions": {
        "ecmaFeatures": {
          "jsx": true
        },
        "ecmaVersion": 2020,
        "sourceType": "module"
      }
    • 자바스크립트 언어 옵션을 지정할 수 있다.
  • env
    "env": {
        "browser": true,
        "node": true
      }
    • 해당 환경에서 정의된 함수나 전역변수를 사용할 수 있게 해준다. 예를 들어 "browser": true를 하게 되면 console.log()를 에러 없이 사용할 수 있게되고, "node":true를 하게되면, require를 에러 없이 사용할 수 있게된다.

ESLint를 처음 접한다면 여기까지 읽고도 eslintrc 설정에 대해 잘 이해가 가지 않을 수 있다.
그런 사람들을 위해 다음 글에서 실제로 기본적으로 많이들 쓰는 plugin을 소개하며 더 자세히 다루어볼 예정이다.

Prettier 설치

yarn add -D prettier

vscode extension 설치

.prettierrc 설정

ESLint와 마찬가지로 설정 파일이 필요하다.
prettier의 각종 옵션을 직접 설정할 수 있다.
어떤 옵션이 있는지는 공식 문서의 이곳에서 확인할 수 있다.

{
 "printWidth": 100,
 "tabWidth": 2,
 "semi": true,
 "singleQuote": true,
 "trailingComma": "all",
 "endOfLine": "auto"
}

이또한 더 자세한 내용은 다음 글에서 다루겠다.

vscode 자체에도 prettier 설정을 해줄 수가 있는데 이것은 프로젝트에 공유되지 않으니 prettierrc 파일에 설정을 하는 것이 좋다.
만약 prettierrc 파일이 있다면 우선적으로 그 설정을 따른다.

ESLint와 Prettier를 함께 사용하기 위해 필요한 것

ESLint의 plugin들의 rule 중 스타일과 관련된 것들도 있기 때문에 종종 Prettier와 충돌하는 일이 생긴다.
이를 방지하기 위해서는 아래 두 가지 plugin을 이용할 수 있다.

  • eslint-config-prettier: Prettier를 ESLint plugin으로 추가한다. 즉, Prettier가 인식하는 코드 포맷 오류를 ESLint 오류로 출력하도록 할 수 있다.
  • eslint-plugin-prettier: ESLint의 코드 포맷과 관련된 rule 중 prettier와 충돌하는 부분을 비활성화할 수 있다.

설치 및 설정 방법은 아래와 같다.

yarn add -D eslint-config-prettier eslint-plugin-prettier
  • eslint-config-prettier
    extends의 가장 마지막에 추가한다.
    {
    "extends": [
      "some-other-config-you-use",
      "prettier"
    ]
    }
  • eslint-plugin-prettier
    {
    "plugins": ["prettier"],
    "rules": {
      "prettier/prettier": "error"
      }
    }

파일 저장 시 자동으로 format 되게 하기

여기까지 설정을 했다면 위에서 설정한 rule들에 어긋나는 코드에 에러/경고 표시가 나게 될 것이다.
그런데 추가적으로 파일 저장 시 어긋난 스타일들을 자동으로 format 해주는 설정을 추가하면 매우 편하다.
이는 vscode의 settings.json에서 formatOnSave를 true로 설정해주면 된다.

때에 따라 formatOnSave가 동작하지 않을 때도 있는데 프로젝트 루트 디렉토리에 .vscode 폴더를 만들고 아래 내용을 settings.json 파일에 넣으면 된다.

.vscode/settings.json

{
    "editor.defaultFormatter": "esbenp.prettier-vscode"
}

참고 자료

https://velog.io/@bab_bury/React-ESLint-Prettier-%EC%84%A4%EC%B9%98-%EB%B0%8F-%EC%84%A4%EC%A0%95
https://kimdabin.tistory.com/entry/Reactjs-ESLint%EC%99%80-Prettier%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%9C-React-%ED%99%98%EA%B2%BD-%EC%84%A4%EC%A0%95-VSCode
https://helloinyong.tistory.com/m/325
https://poiemaweb.com/
https://prettier.io/
https://eslint.org/

profile
Sharing is Caring. 🪐

4개의 댓글

comment-user-thumbnail
2022년 4월 24일

ESLint와 Prettier를 함께 쓸 수 있어서 ISTJ인 저는 너무 행복하네요..

1개의 답글
comment-user-thumbnail
2022년 4월 24일

주영이 발표 체고여써 즐찾해놓고 까머글때마다 볼거얏!!!!!!!!

1개의 답글