Front-End(Web)/React - 프레임워크(React, Next)

[Next.js + TS] 초기세팅 - (2) ESLint, Prettier

ttaeng_99 2021. 10. 14. 05:15
반응형

지난, CRA 초기세팅 및 Typescript 세팅에 이은 2번째 글이다. 주제는 ESLint, Prettier!

뒤에서도 설명하겠지만, 이 툴들은 기능적인 부분보다는 동기들과의 프로젝트 협업을 위한 세팅에 사용되었다.

이들의 역할을 알아보고, 나도 단순히 적용만 하고 지나쳤던 설정들에 대해 자세히 알아보았다.


📓 ESLint

- 개요

ESLint는 Javascript, Typescript 의 코딩 스타일 도구이다. JS코드가 ECMAScript Specification에 부합하는지 검사하는 툴이다.

코딩 스타일 가이드라인을 지정하여, 패턴을 준수하지 않을 경우 사후에 발생할 수 있는 잠재적 문제점을 사전에 방지하기 위해 사용되는 것이다.

* 본래, TS는 TSLint 라는 코딩 스타일 도구가 있었으나, 현재는 ESLint 하나로 모두 linting이 가능 (단, TS는 별도 플러그인 필요)

 

- 설치 및 적용

먼저, VSCode 기준으로 위 Extension을 설치해준다.

 

npm i -D eslint

그리고, 프로젝트에서 eslint 설치를 위해 위 커맨드를 입력한다.

이 때, 개발환경에서만 사용하기 위해 -D(development)로 지정한다.

 

npx eslint --init

다음으로, 프로젝트 루트에서 eslint를 실행시켜준다. 몇 가지 질문들이 나오며, 프로젝트 상황에 맞게 답변하면 된다.

? How would you like to use ESLint?
    ❯ To check syntax and find problems
? What type of modules does your project use?
    ❯ None of these
? Which framework does your project use?
    ❯ None of these
? Does your project use TypeScript?
    ❯ No
? Where does your code run?
    ❯ browser
? What format do you want your config file to be in?
    ❯ JavaScript

 

이를 마치면, 루트 경로에 .eslintrc.js 파일이 생성된다. 여기서, ESLint 관련된 세부설정이 가능하다.

 

- 설정 (.eslintrc.js)

{
  "parser": "@typescript-eslint/parser",
  "parserOptions":  {
    "ecmaVersion":  2018,  // 최신 문법 지원
    "sourceType":  "module",  // 모듈 시스템 사용시
    "ecmaFeatures":  {
      "jsx":  true  // 리액트의 JSX 파싱을 위해서
    }
  },
  "plugins": ["react", "@typescript-eslint", "prettier"],
  "extends": [
    "plugin:react/recommended", // 리액트 추천 룰셋
    "plugin:@typescript-eslint/recommended", // 타입스크립트 추천 룰셋
     // eslint의 typescript 포매팅 기능을 제거(eslint-config-prettier)
    "prettier/@typescript-eslint",  
    // eslint의 포매팅 기능을 prettier로 사용함. 항상 마지막에 세팅 되어야 함.            
    "plugin:prettier/recommended"  // (eslint-plugin-prettier)
  ],
  "settings":  {
    "react":  {
      "version":  "detect"  // eslint-plugin-react가 자동 리액트버전탐지
    },
  }
}

위 파일 역시, 내 미니 프로젝트에서 설정했던 ESLint 항목들이다. 간략적인 설명은 주석을 참고 바란다.

대표적인 옵션들에 대해서 이번 기회에 공부 및 아래와 같이 정리해보았다.

 

1) parser(파서)

 

ESLint는 구문 분석을 위해 기본적으로 Espree 파서를 사용한다.

이외에도, Babel과 함께 사용되는 babel-eslint, TS 구문 분석을 위해 사용되는 @typescript-eslint/parser 등이 있다.

 

 

2) parserOptions(파서 옵션)

 

ESLint 사용을 위해 지원하려는 Javascript 언어의 옵션을 지정할 수 있다. 버전 및 모듈사용 여부 등을 설정한다.

  • ecmaVersion : 사용할 ECMAScript 버전 설정
  • sourceType : parser의 export 형태를 설정
  • ecmaFeatures : ECMAScript 언어 확장 기능을 설정
    • globalReturn - 전역 스코프 사용 여부 (node, common.js 환경에서 최상위 스코프는 module)
    • impliedStric - strict mode 사용 여부
    • jsx - ECMAScript 규격의 JSX 사용 여부
{
  "parserOptions": {
    "ecmaVersion": 6,
    "sourceType": "module",
    "ecmaFeatures": {
      "jsx": true
    }
  }
}

 

 

3) plugins(플러그인)

 

ESLint 문법이 정의된 npm 모듈이다. 통상, eslint-plugin-[플러그인 이름] 으로 명명된다.

 

 

4) extends(확장)

 

extends는 추가한 플러그인을 사용할 규칙을 설정한다.

플러그인은 일련의 규칙의 집합이며, 플러그인을 추가하여도 모든 규칙이 적용되지 않는다.

그렇기에, 플러그인에 속한 규칙을 사용하기 위해 extends에서 설정해줘야하는 것이다.

// 예시) React 플러그인
{
  "plugins": [
    "react"
  ],
  "extends": [
    "eslint:recommended",
    "plugin:react/recommended" 
  ],
}

 

5) rules(규칙)

 

ESLint에는 프로젝트에서 사용하는 규칙을 수정할 수 있다. 규칙은 기본적으로 아래 옵션과, 추가옵션은 배열 리터럴 구문으로 지정한다.

  • "off" 또는 0 : 규칙을 사용하지 않음
  • "warn" 또는 1 : 규칙을 경고로 사용
  • "error" 또는 2 : 규칙을 오류로 사용
{
  "rules": {
    // 세미콜론은 사용하지 않으며 사용할시 경고를 띄움
    "semi": ["warn", "never"]
	  // 더블쿼터(")만을 사용하며 백틱(TemplateLiterals)은 허용됨. 어길시 에러를 발생시킴.
    "quotes": ["error", "double", { "allowTemplateLiterals": true }] 
  }
}

 

 

6) env(환경)

 

env는 global 객체를 ESLint가 인식하게 하는 부분으로, 대표적으로 "browser": true 로 설정하면 window 혹은 document 로 할당되는 것이다.

 

 

7) settings

 

모든 규칙에 의해 공유되는 설정을 하는 부분이며, 대표적으로는 절대경로를 src 폴더에서 사용하기 위해 설정하는 경우가 있다.

{
  "settings": {
    "import/resolver": {
      "node": {
        "paths": ["src"]
      }
    }
  }
}

 

 

8) 기타

 

* 인라인으로 규칙 비활성화

// 전체 파일 규칙 경고 비활성화, 파일 맨위에 아래 블록 주석 추가
/* eslint-disable */
alert('foo');

// 경고 비활성화 블록 주석
/* eslint-disable */
alert('foo');
/* eslint-enable */

// 특정 규칙 경고 비활성화
/* eslint-disable no-alert, no-console */
alert('foo');
console.log('bar');
/* eslint-enable no-alert, no-console */

 

* overrides : 파일 그룹에 대해서만 규칙 비활성화

{
  "rules": {...},
  "overrides": [
    {
      "files": ["*-test.js","*.spec.js"],
      "rules": {
        "no-unused-expressions": "off"
      }
    }
  ]
}

 

* 파일 디렉토리 제외 : ignorePatterns 필드에서 설정하거나, .eslintignore 파일을 작성하여 파일 및 디렉토리 제외

// .eslintrc 파일 ignorePatterns 설정
{
  "ignorePatterns": ["temp.js", "node_modules/"],
    "rules": {
      //...
  }
}

//.eslintignore 파일 생성
/root/src/*.js

.eslintignore 를 현재가 아닌 다른 디렉토리에서 제외파일을 사용하려면, --ignore-path 옵션을 사용할 수 있다.

eslint --ignore-path .gitignore file.js

 

* 구성 파일 사용

ESLint는 루트 디렉토리까지 구성파일을 찾는다.

특히, .eslintrc 와 package.json 파일이 같은 디렉토리에 있다면, .eslintrc가 우선순위를 가지므로 아래처럼 선언한다.

// package.json
eslintConfig = {
  root: ture,
  ...
}

// .eslintrc.*
{ 
  root: true,
  ...
}

📓 Prettier

- 개요

Prettier는 Code Formatter 이다. 코드를 정리할 때, 일정한 형식으로 맞춰주는 툴인 것이다.

문법적인 부분보다는, 개발자들간의 협업을 할 때 코드 스타일이 분화되는것을 최소화하기 위한 목적이 크다.

 

- 설치 및 적용

마찬가지로, VSCode Extension을 설치해준다.

 

npm i -D prettier

// Prettier 및 Plugin 설치
npm i -D prettier eslint-config-prettier eslint-plugin-prettier

프로젝트에서 Prettier를 설치를 위해 위 커맨드를 입력한다.

마찬가지로, 개발환경에서만 사용하기 위해 -D(development)로 지정한다.

 

마찬가지로, 프로젝트 루트 디렉토리에 .prettierrc 파일이 생성되며, 여기서 세부적인 설정이 가능하다.

 

 

- 의존성 설치 및 .eslintrc 적용

마지막으로, ESLint와 혼용해서 사용하는 경우 충돌방지를 위해 위같이 의존성을 설치해준다.

npm i -D eslint-plugin-prettier eslint-config-prettier
  • eslint-config-prettier : 불필요하거나 Prettier과 충돌할 수 있는 모든 규칙을 비활성화
  • eslint-plugin-prettier : 코드 포매팅 시 Prettier를 사용하게 만드는 규칙 추가

 

module.exports = {
  root: true,
  parser: '@typescript-eslint/parser',
  plugins: ['@typescript-eslint', 'prettier'],
  extends: ['standard-with-typescript', 'prettier', 'plugin:prettier/recommended'],
  parserOptions: {
    project: './tsconfig.json',
  },
  rules: {
    '@typescript-eslint/semi': 'off',
    '@typescript-eslint/space-before-function-paren': 'off',
  },
};

이를 위처럼 .eslintrc에 반영하면 된다. 이래도 충돌하는 경우, rules에서 해당 속성을 off 처리하면 된다.

 

- 설정(.prettierrc)

{
  "singleQuote": true,
  "semi": true,
  "useTabs": false,
  "tabWidth": 2,
  "trailingComma": "es5",
  "bracketSpacing": true,
  "jsxBracketSameLine": false,
  "arrowParens": "always"
}

마찬가지로, 내 프로젝트에서 사용한 .prettierrc 파일이다.

semi, jsxBracketSameLine 등은 디폴트 값이나, 많이 설정되는 옵션들에 대해 같이 작업하는 동료들에게 의미를 명시하기 위해 주석을 첨부하고자 해당 코드를 추가했다.

 

* 전체 옵션

{
  "arrowParens": "avoid", // 화살표 함수 괄호 사용 방식
  "bracketSpacing": false, // 객체 리터럴에서 괄호에 공백 삽입 여부 
  "endOfLine": "auto", // EoF 방식, OS별로 처리 방식이 다름 
  "htmlWhitespaceSensitivity": "css", // HTML 공백 감도 설정
  "jsxBracketSameLine": false, // JSX의 마지막 `>`를 다음 줄로 내릴지 여부 
  "jsxSingleQuote": false, // JSX에 singe 쿼테이션 사용 여부
  "printWidth": 80, //  줄 바꿈 할 폭 길이
  "proseWrap": "preserve", // markdown 텍스트의 줄바꿈 방식 (v1.8.2)
  "quoteProps": "as-needed" // 객체 속성에 쿼테이션 적용 방식
  "semi": true, // 세미콜론 사용 여부
  "singleQuote": true, // single 쿼테이션 사용 여부
  "tabWidth": 2, // 탭 너비 
  "trailingComma": "all", // 여러 줄을 사용할 때, 후행 콤마 사용 방식
  "useTabs": false, // 탭 사용 여부
  "vueIndentScriptAndStyle": true, // Vue 파일의 script와 style 태그의 들여쓰기 여부 (v1.19.0)
  "parser": '', // 사용할 parser를 지정, 자동으로 지정됨
  "filepath": '', // parser를 유추할 수 있는 파일을 지정
  "rangeStart": 0, // 포맷팅을 부분 적용할 파일의 시작 라인 지정
  "rangeEnd": Infinity, // 포맷팅 부분 적용할 파일의 끝 라인 지정,
  "requirePragma": false, // 파일 상단에 미리 정의된 주석을 작성하고 Pragma로 포맷팅 사용 여부 지정 (v1.8.0)
  "insertPragma": false, // 미리 정의된 @format marker의 사용 여부 (v1.8.0)
  "overrides": [ 
    {
      "files": "*.json",
      "options": {
        "printWidth": 200
      }
    }
  ], // 특정 파일별로 옵션을 다르게 지정함, ESLint 방식 사용
}

사실, ESLint, Prettier 모두 프로젝트의 기능적으로 이점이 되는 툴보다는, 협업에 의의가 있는 툴이다.

그렇기에, 대충 default 세팅만 가져가고 신경쓰지 않곤 했는데, 그 의미를 이번 기회에 명확하게 알고 정리하게 되었다.

 

이전 팀 프로젝트 떄, 단순히 Airbnb 린트만 가져왔을 떄 적용이 안 된 이유를 이번에 깨닫게 되었다.

(아마, 당시에 구체적으로 extends를 설정하지 않아 내 VSCode 에서 적용되지 않았던 것 같다.)

 

또한, ESLint는 JS파서도 적용하므로, 프로젝트가 Next.js, TS 등 어떤 환경을 쓰는가에 따라 적정한 파서를 설정하는 것 역시 신경써야함을 느꼈다.

 

 

다음 3번째 포스팅은 Babel에 대해 진행하려고 한다.

모듈 import 절대경로 설정, Next.js SSR 시 Styled-Components 초기 스타일링을 위해 설정한 Babel을 정리해보겠다! 

 

[참고]

- [초기세팅 전체] junghyeonsu 님의 블로그 : https://velog.io/@junghyeonsu/React-create-react-app-Typescript-%EC%B4%88%EA%B8%B0-%EC%84%B8%ED%8C%85-%EC%99%84%EB%B2%BD-%EC%A0%95%EB%A6%AC

- [초기세팅 전체] miiunii 님의 블로그 : https://velog.io/@miiunii/CRACreate-React-App%EC%9C%BC%EB%A1%9C-Typescript-%EC%84%A4%EC%A0%95%ED%95%98%EA%B8%B0

- [ESLint] kyusung 님의 블로그 : https://velog.io/@kyusung/eslint-config-2

- [ESLint] rexiann 님의 블로그 : https://rexiann.github.io/2020/12/13/what-is-eslint.html  

- [Prettier] seonghui 님의 블로그 : https://seonghui.github.io/blog/2020/12/27/typescript-eslint-prettier/

반응형