team logo icon

Prettier, ESLint에 대해

ESLint, Prettier 공유과제입니다

Prettier란?


  • Prettier는 코드 포맷터(code Formatter) 중 하나로 작성된 코드의 스타일을 일관되게 유지해주면서 보기 좋게 정렬해주는 기능을 제공하는 도구이다.

  • vite를 사용하여 프로젝트를 생성하면 eslint는 자동으로 깔리지만 Prettier는 자동으로 깔리지 않는다. 따라서 따로 설치를 진행해야 한다!

Prettier 적용하기


1. 설치

  • Prettier 설치하는 명령어

    yarn add -D prettier
  • ✅  왜 add 명령어 뒤에 -D가 붙을까?

    -D 명령어를 사용하면 설치된 라이브러리가 dependencies가 아닌 devDependencies에 보관된다.

    라이브러리를 설치하면 기본적으로 package.json 파일안에 있는 dependencies 객체에 보관된다. dependencies에 담긴 라이브러리들은 배포할 때 필요해서 포함되는 라이브러리들이다. 하지만 우리가 사용할 PrettierESLint 같은 경우는 개발할 때 필요한 라이브러리로 배포를 할때 필요없는 라이브러리들이다. 따라서 이런 어플의 로직과 직접적인 연관이 없는 라이브러리들은 -D를 사용해 devDependencies에 따로 보관한다.

  • Prettier - code formatter VSCode extension 설치

    prettier와 eslint는 런타임에 실행되는것이 아닌 VSCode 에디터가 실행해주는 것이므로 extension을 꼭 설치해줘야 적용된다!

    스크린샷 2024-05-09 오전 4.16.00.png

  • 설정(cmd + , )에서 Editor: Default Formatter 검색 후 Prettier - Code Formatter 선택

    Untitled

2. prettier 설정

  • Prettier를 설정하는 방법은 여러가지가 있지만 우리는 별도의 설정파일인 .prettierrc 를 사용하여 설정할 것이다. .prettierrc 파일 안에 옵션들을 지정해주면 해당 옵션들이 적용된다!

  • 아래는 이번 합동세미나에서 리드분이 추천해준 Prettier 설정이다. 다른 옵션들을 살펴본 결과 바꿀 필요가 없을것 같아서 그래도 사용하기로 했다.

    // .prettierrc
    {
      "printWidth": 120, // 한 줄의 최대 글자수 [80]
      "tabWidth": 2, // 탭 너비 조절 [2]
      "semi": true, // 각 문장 뒤에 세미콜론 자동으로 붙여주기
      "singleQuote": true, // 문자열 사용시 쌍따옴표 대신 홀따옴표 사용
      "trailingComma": "es5", // 객체, 배열등에서 마지막 항목 뒤에 , 사용할 것인지 지정한다. [none, es5, all]
      "requirePragma": false, // 파일 상단에 미리 정의된 주석을 작성 - false가 기본값임
      "arrowParens": "always", // 화살표 함수 매개변수 1개일때()로 감싸주기 - [avoid, always]
      "bracketSameLine": true, // 마지막 > 밑으로 내릴지 말지
      "endOfLine": "auto" // Eof 방식을 설정 auto면 개행문자를 현재 운영체제에 맞게 설정
    }
    • ✅ 복붙용 주석 제거

      {
        "printWidth": 120,
        "tabWidth": 2,
        "semi": true,
        "singleQuote": true,
        "trailingComma": "es5",
        "requirePragma": false,
        "arrowParens": "always",
        "bracketSameLine": true,
        "endOfLine": "auto"
      }
  • prettier는 기본적으로 Git에서 사용하는 디렉토리나 node_modules 디렉토리를 상대로는 포맷팅을 하지 않는다.

  • 만일 추가적으로 prettier가 적용되면 안되는 파일이 존재한다면 .prettierignore 파일을 만들어 관리해주어야 한다.

    // dist 디렉토리, package.json, package-lock.json 파일을 제외한 예시
    // .prettierignore
    dist
    package.json
    package-lock.json

3. Prettier 자동화

  1. VSCode의 settings.json 에서 아래 코드 추가

    "editor.formatOnSave" : true, // prettier 자동 수정
  2. 설정(cmd + , )에서 editor format on save 검색 후 체크박스 체크해주기

    Untitled

ESLint란?


<aside> 💡 ESLint is a tool for identifying and reporting on patterns found in ECMAScript/JavaScript code, with the goal of making code more consistent and avoiding bugs. ESLint는 ECMAscript/JavaScript 코드에서 발견되는 패턴을 식별하고 보고하기 위한 도구로, 코드의 일관성을 높이고 버그를 방지하는 것을 목표로 합니다.

출처 : ESLint 공식문서

</aside>

ESLint는 ES + Lint 를 합친 것으로 ES는 EcmaScript(javaScrip)t를 의미하고 Lint는 에러가 있는 코드에 표시를 달아놓는 것을 의미한다. 즉, ESLint는 자바스크립트 문법에서 에러가 발생하면 표시해주는 도구이다.

사전준비


ESLint를 사용하기 위해서는 SSL을 지원하는 Node.js (^18.18.0^20.9.0, or >=21.1.0) 가 설치되어있어야 한다. (공식사이트에서 Node.js를 다운받으면 SSL은 항상 내장되어있다.)

  • ✅ SSL?

    보안 소켓 계층(Secure Sockets Layer, SSL) 인증서는 종종 디지털 인증서로 불리며, 브라우저(사용자의 컴퓨터)와 서버(웹사이트) 사이의 암호화된 연결을 수립하는 데 사용됩니다.

ESLint의 기본 사용법


ESLint 설치하는 명령어

npm init @eslint/config@latest
  • ✅ Config?

    • configuration(환경 설정)의 줄인 말

    • 프로그램의 매개 변수나 초기 설정 등을 구성하는데 사용하는 파일

config를 사용하고 싶으면 --config 옵션을 사용하고 뒤에 package name을 적어주면 사용할 수 있다.

# 'eslint-config-standard' config 사용
npm init @eslint/config@latest -- --config eslint-config-standard

<aside> 💡 npm init @eslint/config@latest 명령어는 package.json 파일이 설치되어있다고 가정하기 때문에 해당 명령어를 실행하기 전에 반드시 npm init / yarn init 명령어를 사용해 package.json 파일을 만들고 실행해줘야 한다!

</aside>

Configuration


ESLint를 깔고 나면 eslint.config.js / eslint.config.mjs 중 하나의 파일이 생성된다.

파일은 배열을 반환해주는데 해당 배열 안에는 configuration 객체들이 존재한다.

configuration 객체는 ESLint rule들을 적용시켜주는 단위라고 생각하면 된다.

configuration 객체는 다음과 같은 속성들을 가진다.

  • name

    • configuration 객체의 이름.

    • error 발생시 error message에서 name 값으로 어떤 config 객체에서 error가 발생했는지 알려준다.

  • files, ignores

    • files : 해당 config 객체를 어떤 파일에 적용시킬지 알려주는 배열

    • 해당 속성이 없을 경우 모든 파일에 적용시킨다.

    • ignores : 해당 config 객체를 어떤 파일에 적용시키지 않을지 알려주는 배열

    • 해당 속성이 없을 경우 files 속성이 가리키는 모든 파일에 config 객체가 적용된다.

    • ✅ files, ignores 경로 작성법

      files와 ignores는 path를 지정할 때 **, * 를 활용하여 적용시킬 파일들을 가리킨다.

      • ** : 0개 이상의 디렉토리 및 모든 하위 디렉토리를 의미

      • * : 단일 디렉토리 / 파일 이름에서 0개 이상의 문자와 일치해야함을 의미

      예시로 이해해보자

      • "src/**/*.js": src 디렉토리 안에 있는 모든 디렉토리 및 하위에 있는 디렉토리 중 .js로 끝나는 모든 파일

      • "src/*/*.js": src 디렉토리 밑에 있는 단일 디렉토리 내에서 .js로 끝나는 모든 파일

      ** 의 경우 본인과 하위의 모든 디렉토리를 포함

      * 의 경우 본인 미포함, 오직 하위에 바로 있는 단일 디렉토리만 포함

      global 하게 적용시키는 방법

      **/*.js : 모든 .js 로 끝나는 파일

  • languageOptions

    • 자바스크립트가 configure를 어떻게 linting하는지 설정하는 option들이 포함된 객체

    • ecmaVersion, sourceType, globals, parser, parserOptions 등이 위치

    • 기존에 .json에서는 따로 빼서 썼던 parser, parserOptions를 config.js 파일에서는 해당 속성에 넣어서 쓴다.

    // eslint.config.js
    import babelParser from "@babel/eslint-parser";
    
    export default [
        {
            languageOptions: {
                parser: babelParser,
                parserOptions: {
                    requireConfigFile: false,
                    babelOptions: {
                      babelrc: false,
                      configFile: false,
                      presets: ["@babel/preset-env"]
                    }
                }
            }
        }
    ];
  • linterOptions

    • linting process와 관련된 설정이 포함된 객체

  • plugins

    • name-value 값으로 이루어진 plugin들이 포함된 객체

    • config.js 에서는 third party plugin들을 import 받아서 사용할 수 있다.

    // eslint.config.js
    import example from "eslint-plugin-example";
    
    export default [
        {
            plugins: {
                example // 그냥 plugin만 써도 되고
                example : example // key값을 지정해서 사용해줘도 된다
            },
            rules: {
                "example/rule1": "warn"
            }
        }
    ];
  • rules

    • configure rule들이 포함된 객체

    • ruleName : error level / ruleName : [error level, ?options]

    • 각 rule들에게 다음의 3가지 error level을 설정할 수 있다.

      1. off / 0 : rule을 적용시키지 않는다.

      2. warn / 1 : rule을 적용시키고 rule 위반시 warning을 띄워준다.

      3. error / 2 : rule을 적용시키고 rule 위반시 error를 띄워준다.

    • options 자리에 rule의 고유한 옵션값을 줄 수 있다.

    // eslint.config.js
    export default [
        {
            rules: {
                "no-unused-vars": "error",
                "no-undef": "error"
                semi: ["error", "never"] 
            }
        }
    ];
  • settings

    • 모든 rules에 적용될 설정이 포함된 객체

ESLint 자동화

VSCode의 settings.json 에서 아래 코드를 추가

"editor.codeActionsOnSave": {
	"source.fixAll.eslint" : true, // eslint 자동 수정
  },

…. 여기까지 config.js 로 설정하는것을 공부하고 설정하려고 했는데…………………………………….. .json 형식으로 지정된 합세 설정파일을 config.js로 바꾸는것은 불가능………………………………………… 하여서 그냥 .json 형식으로 사용하기로 했습ㄴ디ㅏ……………………………. 아니 이 망할 한국인들아 왜 config.js 아무도 안써 아티클이 없어 왜!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

ESLint 설정하기


  • vite로 React 프로젝트 만들기

    # React 폴더 설정
    yarn create vite
  • 몇가지 질문이 나오는데 우리는 ts를 사용하므로 다음과 같이 선택

    1. Project name 설정

    2. React 선택

    3. TypeScript + SWC 선택

  • 폴더가 만들어지면 vite는 자동으로 eslint가 설치되고 .eslintrc.cjs 파일이 설정파일로 생긴다.

    <aside> 💡 자동으로 설치된 eslint는 최신버전으로 9.2.0버전이 깔린다. 하지만 현재 Eslint 개발자들이 일을 대충하는지 최신버전이랑 호환이 안되는 rule들이 많아서 버전을 다운그레이드해서 사용하자! yarn add eslint@8.57.0

    </aside>

  • 위의 과정을 따랐다면 아래의 라이브러리들이 자동으로 설치되어 있다.

    "@types/react": "^18.2.66",
    "@types/react-dom": "^18.2.22",
    "@typescript-eslint/eslint-plugin": "^7.2.0",
    "@typescript-eslint/parser": "^7.2.0",
    "@vitejs/plugin-react-swc": "^3.5.0",
    "eslint": "^8.57.0",
    "eslint-plugin-react-hooks": "^4.6.0",
    "eslint-plugin-react-refresh": "^0.4.6",
    "typescript": "^5.2.2",
  • 이제 plugin으로 사용할 eslint 라이브러리들을 설치해주자.

    yarn add -D eslint-config-prettier eslint-plugin-prettier eslint-plugin-react eslint-plugin-jsx-a11y eslint-plugin-simple-import-sort eslint-plugin-import
    • ✅ 사용되는 라이브러리 설명

      • eslint-config-prettier

        eslint에서 prettier와 겹치거나 충돌하는 규칙을 삭제한다.

      • eslint-plugin-prettier

        eslint에 prettier의 포매팅 기능을 추가한다.

      • eslint-plugin-import

        import/export 문법의 린팅을 지원하고, 파일 경로와 import 이름의 오타를 예방한다.

      • eslint-plugin-react

        react에 필요한 린팅 규칙을 추가한다.

      • eslint-plugin-react-hooks

        react hooks에 필요한 린팅 규칙을 추가한다.

      • eslint-plugin-jsx-a11y

        JSX 내의 접근성 문제에 대해 즉각적인 AST 린팅 피드백을 제공한다.

        • 추가설명

          • a11y : 웹 접근성의 별칭

          • AST : Abstract Syntax Tree

          • This plugin does a static evaluation of the JSX to spot accessibility issues in React apps. Because it only catches errors in static code, use it in combination with @axe-core/react to test the accessibility of the rendered DOM. Consider these tools just as one step of a larger a11y testing process and always test your apps with assistive technology.

      • eslint-plugin-simple-import-sort

        import문 순서 자동 정렬

      • @typescript-eslint/eslint-plugin

        typescript 관련 린팅규칙을 설정한다.

      • @typescript-eslint/parser

        typescript를 parsing하기 위해 사용한다. (typescript에 대한 AST 생성)

  • 여기서 config.js 파일로 너무너무 바꾸고 싶었지만 일단 눈물을 머금고 .eslintrc.cjs 파일을 삭제하고 .eslintrc.json 파일을 생성한다.

  • .eslintrc.json 파일에 우리 합세 조의 eslint 설정을 넣어준다.

    {
      // 실행 환경 설정
      "env": {
        "browser": true,
        "es2021": true,
        "node": true,
        "es6": true
      },
      "plugins": [
        "react",
        "react-hooks",
        "@typescript-eslint",
        "@typescript-eslint/eslint-plugin",
        "simple-import-sort",
        "jsx-a11y",
        "prettier",
    		"import",
      ],
      "extends": [
        "eslint:recommended",
        "plugin:react/recommended",
        "plugin:@typescript-eslint/eslint-recommended",
        "plugin:@typescript-eslint/recommended",
        "plugin:react-hooks/recommended",
        "plugin:prettier/recommended",
        "plugin:import/recommended",
        "plugin:import/typescript",
        "plugin:jsx-a11y/recommended"
      ],
      "rules": {
        "indent": ["error", 2, { "SwitchCase": 1 }], // 들여쓰기 몇 칸? 기본 2칸으로 하되, switch문에서는 1칸으로 지정
        "quotes": ["off", "single"], // 쌍따옴표가 아닌 홑따옴표를 사용
        "semi": ["error", "always"], // semi colon을 강제함
        "no-multiple-empty-lines": ["error", { "max": 1, "maxEOF": 0 }],
        "no-multi-spaces": "error", // 스페이스 여러개 금지
        "object-curly-spacing": ["error", "always"], // 객체 괄호 앞 뒤 공백 추가
        "space-in-parens": ["error", "never"], // 일반 괄호 앞 뒤 공백 추가
        "computed-property-spacing": ["error", "never"], // 대괄호 앞 뒤 공백 추가하지 않음
        "comma-spacing": ["error", { "before": false, "after": true }], // 반점 앞 뒤 공백: 앞에는 없고, 뒤에는 있게
        "eol-last": ["error", "always"], // line의 가장 마지막 줄에는 개행 넣기
        "no-tabs": ["error", { "allowIndentationTabs": true }], // \\t의 사용을 금지하고 tab키의 사용은 허용
        "react-hooks/rules-of-hooks": "error", // Checks rules of Hooks
        "react-hooks/exhaustive-deps": "off", // Checks effect dependencies
        "react/react-in-jsx-scope": "off", // import React from "react"가 필수였던 시기에 필요한 규칙이므로 off
        "simple-import-sort/imports": "error", //import 정렬 강제
        "simple-import-sort/exports": "error", //export 정렬 강제
        "no-unused-vars": "warn",
        "no-console": "warn",
        "import/order": [
          "error",
          {
            // 1. node "builtin" modules
            //import fs from 'fs';
            // 2. "external" modules
            //import _ from 'lodash';
            // 3. "internal" modules
            //import foo from 'src/foo';
            "groups": ["builtin", "external", ["parent", "sibling"], "index"], // import 되는 순서 정의
            "pathGroups": [
              {
                "pattern": "react*", // path가 react로 시작하면
                "group": "external", // external 앞에
                "position": "before"
              }
            ],
            "alphabetize": {
              "order": "asc",
              "caseInsensitive": true
            },
            "newlines-between": "always" // group들 사이마다 개행 적용 (group 내부에서 개행 적용 불가)
          }
        ]
      },
      "parser": "@typescript-eslint/parser",
      "parserOptions": {
        "ecmaFeatures": {
          "jsx": true
        },
        "ecmaVersion": "latest",
        "sourceType": "module"
      },
    
      "settings": {
        "import/resolver": {
          "node": {
            "moduleDirectory": ["node_modules", "src/"],
            "extensions": [".js", ".jsx", ".ts", ".tsx", ".d.ts"]
          }
        },
        "react": {
          "version": "detect"
        },
        "import/parsers": {
          "@typescript-eslint/parser": [".ts", ".tsx", ".js"]
        }
      }
    }
  • 이제 설정이 끝났으니 ESLint VSCode extension 설치

    Untitled

  • ESLint 자동화

    "editor.codeActionsOnSave": {
    	"source.fixAll.eslint" : true, // eslint 자동 수정
      },


최신 아티클
lighthouse에 대해
문성희
|
2024.05.13
lighthouse에 대해
lighthouse에 대해
prettier, eslint, styleLint에 대해
이진
|
2024.05.10
prettier, eslint, styleLint에 대해
4주차 공유과제
Article Thumbnail
박채연
|
2024.05.10
Prettier, ESLint, StyleLint
prettier, eslint, stylelint