React - ESlint & Prettier

homewiz·2024년 3월 29일

React & typescript

목록 보기
2/18

intro

협업 프로젝트시에 코딩룰이 적용된 소스는 인체에 유익 하다는 전제 하에 강제하는 방법을 알아 본다.
확실히 쌩 리액트 프로젝트를 구성을 위해서는 webpack을 만저볼수 밖에 없는데 이점이 상당히 도움이 된다는 것을 몸소 체험한다.
CAR-ESLint & prettier 세팅 할때는 구성 요소중 30%정도는 남들이 하니깐 가이드에 나와 있으니깐 대충 넘어 갔던것들이 눈에 들어 온다.

1. Terms

Is prettier ?

MIT license를 가진 code formatter 모듈입니다. Code format이란 줄 바꿈, 줄간격, 괄호의 위치 등 여러 가지 Style을 의미하며, Prettier는 이런 code style을 자동적으로 정리해 줍니다.

Is eslint?

javascript 정적 분석 도구

ESLint란? ECMAScript Lint의 줄임말로, javascript의 표준을 다루는 협회가 바로 ECMA입니다. Lint는 유닉스 시절에 정적코드 분석 프로그램인 'Linter"에서 따온 이름입니다.

2. VSCode Extention ESLint

  • complie 전 코딩단계에서도 문법 오류 힌트가 발생하게 해준다.
  • Ctrl + Shift + X를 통해 Extention으로 이동
  • 검색 창에 ESLint 검색 후 설치
  • ctrl + shift + p > reload window 재실행
  • App.js 아래와 같이 오류 구문에 밑줄 발생

.vscode/settings.json

{
  "files.eol": "\n",
  "[javascript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[javascriptreact]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[css]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.formatOnSave": true,
  "editor.codeActionsOnSave": {
    "source.organizeImports": "always",
    "source.fixAll": "always",
    "source.fixAll.eslint": "explicit"
  },
  "eslint.validate": [
    "javascript",
    "javascriptreact",
    "typescript",
    "typescriptreact",
    "tsx",
    "jsx"
  ],
  "eslint.experimental.useFlatConfig": true,
  "eslint.workingDirectories": [
    {
      "mode": "auto"
    }
  ],
  "editor.quickSuggestions": {
    "strings": true
  }
}

3. VSCode Extention Prettier

  • 세미콜론, 줄간격, 내려쓰기등 간단한 규칙을 자동으로 수정 해주는 툴
  • Extention > Prettier 검색 후 Prettier-code formatter 설치

  • setting.json
    1. open setting json (ctrl + shift + p)
    2. input "open user setting"
    3. add line ------
      "editor.defaultFormatter": "esbenp.prettier-vscode",
      "editor.formatOnSave": true,
      "editor.codeActionsOnSave": {
      "source.fixAll.eslint": true
      }

  • set settings
  1. open setting(ctrl + ,)
  2. search "default formatter" > select Prettier-Code fromatter
  3. search "FormatOnSave" > check box: true
  • 저장시 변경 기능을 사용 하지 않을 경우 shift + alt + f 키를 통해 자동 수정 이용 가능

  • App.js에서 아래와 같이 시작 p 태그 라인이 맞지 않는 경우
<img src={logo} className="App-logo" alt="logo" />
                  <p>
		Edit <code>src/App.js</code> and save to reload.
	</p>

shift + alt + f를 누르면 아래와 같이 자동으로 잡아 준다.

<img src={logo} className="App-logo" alt="logo" />
	<p>
		Edit <code>src/App.js</code> and save to reload.
	</p>

4. Install Plugins

for React & javascript

yarn add -D eslint prettier eslint-plugin-prettier eslint-plugin-react eslint-plugin-react-hooks eslint-plugin-jsx-a11y eslint-config-prettier eslint-webpack-plugin
yarn add -D @typescript-eslint/eslint-plugin @typescript-eslint/parser

prettier : auto code formatter module

eslint-plugin-prettier : eslint와 prettier간 충돌방지 플러그인

eslint-plugin-react : for react 구문

eslint-plugin-react-hooks : for react hooks 구문

eslint-plugin-jsx-a11y : for jsx(xml) 정적 분석

eslint-config-prettier : prettier eslint 충동 방지

@typescript-eslint/eslint-plugin: An ESLint plugin which provides lint rules for TypeScript codebases.

@typescript-eslint/parser:TypeScript ESTree를 활용하여 ESLint가 TypeScript 소스 코드를 린트할 수 있도록 하는 ESLint 파서.

eslint-webpack-plugin: 규칙을 만족하지 못하는 코드가 있으면 터미널과 콘솔창에 에러를 발생, 빌드 에러

5. Set Config

touch eslint.config.js && touch .prettierrc.json

./eslint.config.js

import parser from "@typescript-eslint/parser";
import jsxA11y from "eslint-plugin-jsx-a11y";
import prettierPlugin from "eslint-plugin-prettier";
import reactPlugin from "eslint-plugin-react";
import reactHooks from "eslint-plugin-react-hooks";
import globals from "globals";

export default [
  {
    files: ["**/*.js", "**/*.ts", "**/*.tsx"],
    languageOptions: {
      parser,
      parserOptions: {
        ecmaVersion: "latest",
        sourceType: "module",
        ecmaFeatures: {
          jsx: true
        }
      },
      globals: {
        ...globals.browser,
        ...globals.node,
        _: true,
        $d: true,
        $t: true,
        $http: true
      }
    },
    plugins: {
      react: reactPlugin,
      "react-hooks": reactHooks,
      "jsx-a11y": jsxA11y,
      prettier: prettierPlugin
    },
    rules: {
      "no-unused-vars": "warn",
      "react/react-in-jsx-scope": "off",
      "react/jsx-key": "error",
      "react/prop-types": "off",
      "react-hooks/exhaustive-deps": "error",
      "jsx-a11y/anchor-is-valid": "off",
      "no-constant-condition": "off",
      "prettier/prettier": "warn"
    }
  }
];

"react/prop-types": "error" 일경우 소스상 문제가 없는 경우에도 error를 발생시키는 경우가 있어off로 전환
대신 typescript 문법 검사를 통해서진행시킨다.

./.prettierrc.json

{
  "endOfLine": "auto",
  "semi": true,
  "singleQuote": false,
  "printWidth": 300,
  "tabWidth": 2,
  "useTabs": false,
  "arrowParens": "avoid",
  "bracketSpacing": true,
  "htmlWhitespaceSensitivity": "css",
  "jsxBracketSameLine": false,
  "jsxSingleQuote": false,
  "proseWrap": "preserve",
  "quoteProps": "as-needed",
  "trailingComma": "none",
  "vueIndentScriptAndStyle": false,
  "filepath": "",
  "requirePragma": false,
  "insertPragma": false,
  "overrides": [
    { "files": "NestedRoutes.js", "options": { "printWidth": 500, "trailingComma": "none" } },
    {
      "files": ["*.json"],
      "options": { "printWidth": 100, "trailingComma": "none" }
    },
    { "files": "*.prettierrc", "options": { "printWidth": 100, "trailingComma": "none" } },
    { "files": "*.code-snippets", "options": { "printWidth": 100, "trailingComma": "none" } }
  ]
}

아래 사이트를 통해 룰 설정을 미리 체험 할 수 있다.
https://prettier.io/playground/

./config/webpack.common.js

import path from "path";
import HtmlWebpackPlugin from "html-webpack-plugin";
import ESLintPlugin from "eslint-webpack-plugin";
import webpack from "webpack";

const Webpack = (env, argv, custom) => {
  const { appName, version, minify } = custom;
  console.log(appName, "build version : ", version, JSON.stringify(argv), JSON.stringify(env), JSON.stringify(custom));
  return {
    entry: { main: "./src/index.tsx" },
    resolve: {
      extensions: [".ts", ".tsx", ".js", ".jsx", ".json", ".css", ".scss"],
      alias: { "@": path.resolve(process.cwd(), "src") },
      symlinks: false,
      cacheWithContext: false
    },
    performance: {
      maxEntrypointSize: 10240000,
      maxAssetSize: 10240000
    },
    module: {
      rules: [
        {
          test: /\.(ts|tsx|js|jsx)$/,
          use: "ts-loader",
          exclude: /node_modules/
        },
        {
          test: /\.md$/,
          use: "ignore-loader"
        }
      ]
    },
    plugins: [
      new webpack.ProvidePlugin({ React: "react" }),
      new HtmlWebpackPlugin({
        title: appName,
        template: "./public/index.html",
        favicon: "./public/favicon.ico",
        minify
      }),
      new ESLintPlugin({
        files: "src",
        extensions: ["js", "jsx", "ts", "tsx"],
        overrideConfigFile: path.resolve(process.cwd(), "eslint.config.js"),
        cache: true,
        failOnError: false
      })
    ]
  };
};

export default Webpack;

빌드시 문법 검사를 위해 ESLintPlugin을 추가 해준다.

6. 문법 검사 테스트

yarn start

혹 아래와 같이 내려 쓰기 에러가 나오는 경우 해당 파일에서
파일 저장 또는 shift + alt + f로 문법 자동고침을 수행해준다.

ERROR in [eslint]
C:\work\react-ts\src\index.tsx
  11:3  error  Insert `␍⏎`  prettier/prettier

✖ 1 problem (1 error, 0 warnings)
  1 error and 0 warnings potentially fixable with the `--fix` option.
  • App.js 소스에 에러 구문을 추가 해본다.
...
const App = () => {
  const a = 0; // error: never used 
  const b = [0, 1, 2, 3, 4];
  return (
    <div>
      {b.map((e) => ( // error: replace
        <div>{e}</div> // error: missing key
      ))}
    </div>
  );
};
...
   4:9   error  'a' is assigned a value but never used      @typescript-eslint/no-unused-vars
   9:14  error  Replace `(e)` with `e`                      prettier/prettier
  10:9   error  Missing "key" prop for element in iterator  react/jsx-key

추가


위와 같이 vscode에서 빨간줄이 가지 않는 경우에는 vscode를 재실행 한다.

ctrl + shift + p

0개의 댓글