ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Next.js + TS] 초기세팅 - (2) ESLint, Prettier
    Front-End(Web)/React - 프레임워크(React, Next) 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/

    반응형
Designed by Tistory.