[React] Typescript + eslint + prettier ์„ค์ •

๊ณตํšจ์€ยท2022๋…„ 1์›” 5์ผ
27

react

๋ชฉ๋ก ๋ณด๊ธฐ
7/10

๐Ÿ˜ Project ํ•  ๋•Œ๋งˆ๋‹ค eslint, prettier ์„ธํŒ… ์‹œ ๋ชจํ˜ธํ–ˆ๋˜ ๊ฒƒ ๋“ค์„ ํ•œ ๋ฒˆ ์ •๋ฆฌํ•ด ๋ณด๋ ค๊ณ  ํ•œ๋‹ค.

Create React App with TypeScript

Create React App์€ ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋ณ„๋„์˜ ์„ค์ • ์—†์ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์ง€์›ํ•œ๋‹ค.

CRA๋กœ ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ

๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜๋ฉด TypeScript๋ฅผ ์ง€์›ํ•˜๋Š” ์ƒˆ๋กœ์šด ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

npx create-react-app my-app --template typescript

์œ„์˜ ๋ช…๋ น์–ด๋กœ ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•˜๋ฉด ์ž๋™์œผ๋กœ tsconfig.json ์ด ์ƒ์„ฑ๋จ
https://www.typescriptlang.org/docs/handbook/tsconfig-json.html
์ˆ˜ ๋งŽ์€ ์ปดํŒŒ์ผ๋Ÿฌ ์˜ต์…˜์„ ๋ณผ ์ˆ˜ ์žˆ์Œ

Setup ESLint

1. default config ์ง€์šฐ๊ธฐ(package.json)

๋” ์ข‹์€ ์„ธํŒ…์„ ํ•˜๊ธฐ์œ„ํ•ด ์•„๋ž˜ ๋ถ€๋ถ„์„ ์ง€์šด๋‹ค.
CRA๋กœ ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•˜๋ฉด package.json์—์„œ ๊ธฐ๋ณธ์ ์œผ๋กœ ์„ธํŒ…๋˜์–ด์žˆ์Œ

  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },

2. install eslint

npm install eslint --save-dev

3. setup eslint

npx eslint --init

์œ„์™€ ๊ฐ™์€ ์ ˆ์ฐจ๋ฅผ ๋”ฐ๋ผ์ฃผ๋ฉด ํ•„์š”ํ•œ package๋“ค์ด ์„ค์น˜๋œ๋‹ค.

.eslintrc.json์„ ํ™•์ธ ํ•ด๋ณด๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ์ž๋™์œผ๋กœ ์„ธํŒ…๋œ๋‹ค.

4. Running ESLint

ํ„ฐ๋ฏธ๋„์„ ์—ด๊ณ  ์•„๋ž˜์™€ ๊ฐ™์€ ๋ช…๋ น์–ด๋ฅผ ์ž…๋ ฅํ•œ๋‹ค...!

npx eslint src/* --fix

์—๋Ÿฌ๊ฐ€ ์ค„์ค„ํžˆ ๋œฌ๋‹ค...ใ…‹ใ…‹ใ…‹

๋Œ€๋ถ€๋ถ„์˜ ์—๋Ÿฌ๋Š” ํ™•์žฅ ํŒŒ์ผ ์˜ค๋ฅ˜๋‚˜ React ์ž์ฒด์˜ ์‚ฌ์šฉ๊ณผ ๊ฐ™์ด ์˜๋ฏธ๊ฐ€ ์—†๋‹ค.
'React' was used before it was defined no-use-before-define
JSX not allowed in files with extension.'tsx' react/jsx-filename-extension

5. ์„ฑ๊ฐ€์‹  ์—๋Ÿฌ๋“ค์„ ํ•ด๊ฒฐํ•˜๊ธฐ์œ„ํ•œ ์†”๋ฃจ์…˜

๐Ÿ˜ˆ problem: "react/jsx-filename-extension"
๐Ÿ˜Š sample: JSX not allowed in files with extension '.tsx'
(ํ™•์žฅ์ž๊ฐ€ '.tsx' ์ธ ํŒŒ์ผ์—์„œ๋Š” jsx๊ฐ€ ํ—ˆ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค)
๐Ÿ† solution

eslintrc.json

"rules":{
  "react/jsx-filename-extension":["warn",{"extensions":[".tsx"]} }
}

์ถ”์ธก jsx๋ฌธ๋ฒ•์„ .tsx์—์„œ๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ฃผ๋Š”๊ฑฐ ๊ฐ™์Œ(?)

๐Ÿ˜ˆ problem: "import/no-unresolved"
๐Ÿ˜Š sample: Unable to resolve path to module './App'
(๋ชจ๋“ˆ './App'์— ๋Œ€ํ•œ ๊ฒฝ๋กœ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.)
๐Ÿ† solution

ํ”„๋กœ์ ํŠธ ๋””๋ ‰ํ† ๋ฆฌ ๋‚ด์—์„œ ํ„ฐ๋ฏธ๋„์„ ์—ด๊ณ  eslint-import-resolver-typescript ํŒจํ‚ค์ง€๋ฅผ ์„ค์น˜ํ•œ๋‹ค.

 npm install eslint-import-resolver-typescript --save-dev

eslintrc.json์— "settings"๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ์•„๋ž˜์™€ ๊ฐ™์ด ์ถ”๊ฐ€ํ•ด์ค€๋‹ค.

"settings":{
  "import/resolver":{
    "typescript":{}
  }
}

๐Ÿ˜ˆ problem: "import/extensions"
๐Ÿ˜Š sample: Missing file extension 'tsx' from './App'
์•„๋‹ˆ ์ด๋ ‡๊ฒŒ ๋˜์–ด์žˆ๊ธธ๋ž˜ App.tsx๋ผ๊ณ  ๋ถ™์˜€๋Š”๋ฐ ๊ฐ€์ ธ์˜ค๊ธฐ ๊ฒฝ๋กœ๋Š” '.tsx' ํ™•์žฅ์œผ๋กœ ๋๋‚  ์ˆ˜ ์—†์œผ๋‹ˆ 'App.js'๋ฅผ ๊ณ ๋ ค ํ•˜๋ผ๋„ค..? js๋Š” ํ™•์žฅ์ž ๋ถ™์ด๋ฉด (lint์—๋Ÿฌ ์—†์ด)๊ฐ€์ ธ์™€์ง!
๐Ÿ† solution

eslintrc.json์œผ๋กœ๊ฐ€์„œ rules์— ์•„๋ž˜์™€ ๊ฐ™์ด ๋„ฃ์–ด์ค€๋‹ค.

"rules":{
  "import/extensions":[
        "error",
        "ignorePackages",
        {
          "ts":"never",
          "tsx":"never"
        }
    ]
}

๐Ÿ˜ˆ problem: "no-undef"
๐Ÿ˜Š sample:"test" is not defined
๐Ÿ† solution
eslintrc.json, extends์— ์•„๋ž˜์™€ ๊ฐ™์ด ์ถ”๊ฐ€ํ•ด์ค€๋‹ค.

"extends":[
  "plugin:@typescript-eslint/recommended"
  ]

6. nice rules!

  • ๋ชจ๋“  ํ•จ์ˆ˜์— ๋ช…์‹œ์  ๋ฐ˜ํ™˜ ์œ ํ˜•์ด ์žˆ์–ด์•ผํ•จ!
    eslintrc.json rules์— ์•„๋ž˜์™€ ๊ฐ™์ด ์ถ”๊ฐ€
"rules":{
  "@typescript-eslint/explicit-function-return-type":[
    "error",
    {
      "allowExpressions":true
    }
    ]
  • ์ฝ”๋“œํ•œ์ค„์˜ ์ตœ๋Œ€๊ธธ์ด
    eslintrc.json rules์— ์•„๋ž˜์™€ ๊ฐ™์ด ์ถ”๊ฐ€
"rules":{
  "max-len":["warn",{"code":80}]
}
  • react hooks rules
    eslintrc.json plugins์— ์•„๋ž˜์™€ ๊ฐ™์ด ์ถ”๊ฐ€
"plugins":[
  "react-hooks"
 ]

eslintrc.json rules์— ์•„๋ž˜์™€ ๊ฐ™์ด ์ถ”๊ฐ€

"rules":{
  "react-hooks/rules-of-hooks":"error",
  "react-hooks/exhaustive-deps":"warn"
}

setup prettier

1. Install prettier package

npm install --save-dev --save-exact prettier

2. .prettierrc.json file

{
  "trailingComma":"es5",
  "tabWidth":4,
  "semi":false,
  "singleQuote":true
}

3. .prettierignore file

.prettierignore file ์ƒ์„ฑ!

node_modules

4. run prettier

npx prettier --write src/App.tsx

์ฝ”๋“œ ํฌ๋งทํŒ…์ด ๋œ๋‹ค! ์•ผํ˜ธ^0^

Prettier with auto-fix in a file when save

๐Ÿ’ก ๋ฐ‘์—์„œ ๋ณด๋ฉด ์•Œ๊ฒ ์ง€๋งŒ eslint formatting rules์™€ prettier ๊ฐ€ ์ถฉ๋Œํ•จ

eslint ์™€ prettier์„ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ prettier ๊ทœ์น™๋งŒ ์‚ฌ์šฉํ•˜์—ฌ ์ž๋™ ์ˆ˜์ •์„ ์„ค์ •ํ•˜๊ณ  prettier ๋ฐ linter ๊ทœ์น™์„ ๋ชจ๋‘ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ๊ถŒ์žฅํ•˜์ง€ ์•Š๋Š”๋‹ค!

ํ”„๋กœ์ ํŠธ ์ตœ์ƒ์œ„ ๊ฒฝ๋กœ์— .vscode ํด๋”๋ฅผ ๋งŒ๋“ค๊ณ  ๊ทธ ์•ˆ์— settings.json ํŒŒ์ผ์„ ๋งŒ๋“ ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์•„๋ž˜์˜ ๋‚ด์šฉ์„ ๋„ฃ๋Š”๋‹ค.

{
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.formatOnSave": true
}

์ด๋ ‡๊ฒŒ ์„ค์ •ํ•ด์ฃผ๊ณ  ์ €์žฅ์„ ํ•ด๋ณด๋ฉด prettierrc์— ์ •์˜๋œ ๋ฃฐ์— ๋”ฐ๋ผ ์ž๋™์œผ๋กœ ์ฝ”๋“œ๊ฐ€ ํฌ๋งทํŒ…๋œ๋‹ค.

ESLint, Prettier ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๊ธฐ

์„ธํŒ…์„ ๋‹ค ํ•˜๊ณ ๋‚˜์„œ ๋‘˜๋‹ค ์‹คํ–‰ํ•˜๊ฒŒ ๋˜๋ฉด formatting ๋ฃฐ์— ๋”ฐ๋ผ ์„œ๋กœ ์ถฉ๋Œ์ด ์ผ์–ด๋‚˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.
์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด formatting ๊ทœ์น™์—๋Š” Prettier๋งŒ ์‚ฌ์šฉํ•˜๋„๋ก ESLint๋ฅผ ์„ค์ •ํ•˜์—ฌ formatting ๊ทœ์น™์ด ์ถฉ๋Œ ํ•˜์ง€ ์•Š๋„๋ก ํ•  ์ˆ˜ ์žˆ๋‹ค.

ESLint formatting rules ๋น„ํ™œ์„ฑํ™”

1.eslint-config-prettier ํŒจํ‚ค์ง€๋ฅผ ์„ค์น˜ํ•œ๋‹ค.

npm install --save-dev eslint-config-prettier

2..eslintrc.json์— eslint-config-prettier ์„ค์ •

"extends":[
  ...
  "prettier",
  "prettier/prettier",
  ]

3. eslint ์‹คํ–‰

npx eslint src/App.tsx ---quiet --fix

ESLint๊ฐ€ formatting rules์‚ฌ์šฉ์„ ์ค‘๋‹จํ•œ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

ESLint๊ฐ€ Prettier ๊ทœ์น™์„ ์‚ฌ์šฉํ•˜๋„๋ก!

1. eslint-plugin-prettier ์„ค์น˜

npm install --save-dev eslint-plugin-prettier

2. .eslintrc.json์— eslint-plugin-prettier ์„ค์ •

"extends":[
  "plugin:prettier/recommended"
  ]

note1: ์ด๊ฒƒ์€ ESLint ๋‚ด์—์„œ Prettier๋ฅผ ์‹คํ–‰ํ•˜๋Š” eslint-plugin-prettier ํ”Œ๋Ÿฌ๊ทธ์ธ์—์„œ ์ œ๊ณตํ•˜๋Š” ๊ทœ์น™์„ ์ผ ๋‹ค.

note2: "plugin:prettier/recommended"๊ฐ€ ์ด๋ฏธ ๋’ค์—์„œ ์ˆ˜ํ–‰ํ•˜๋ฏ€๋กœ "extends"์—์„œ "prettier"๋ฅผ ์ œ๊ฑฐ ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

3. ESLint๋ฅผ ์‹คํ–‰ํ•œ๋‹ค.

npx eslint src/App.tsx --quiet --fix

ESLint๋Š” formatting rules ๋กœ Prettier ๊ตฌ์„ฑ์„ ์‚ฌ์šฉํ•œ๋‹ค.

์ €์žฅํ•  ๋•Œ ํŒŒ์ผ์—์„œ ์ž๋™์œผ๋กœ ESLint + Pretter ์‹คํ–‰ ๋˜๋„๋ก ํ•˜๊ธฐ

.vscode/settings.json์— ์•„๋ž˜์™€ ๊ฐ™์ด ์ถ”๊ฐ€ํ•ด์ค€๋‹ค.

{
  "editor.defaultFormatter": "dbaeumer.vscode-eslint",
  "editor.formatOnSave": true,
  "eslint.alwaysShowStatus": true,
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true
  }
}

์™„๋ฃŒ! ์ด์ œ ์ €์žฅ๋œ ๋ชจ๋“  ํŒŒ์ผ์€ ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•˜๊ณ  ์ž๋™์œผ๋กœ ์ˆ˜์ • ๋  ์ˆ˜ ์žˆ๋Š” ESLint + Prettier ๊ทœ์น™์œผ๋กœ ํ˜•์‹์„ ์ง€์ •ํ•œ๋‹ค.

What is ESLint

JavaScript ์ฝ”๋“œ์—์„œ ๋ฌธ์ œ๋ฅผ ์ฐพ์•„์ฃผ๊ณ  ๊ณ ์ณ์ฃผ๋Š” ์ •์  ์ฝ”๋“œ ๋ถ„์„ ๋„๊ตฌ์ด๋‹ค. create-react-app ์œผ๋กœ ๋ฆฌ์•กํŠธ ์•ฑ์„ ์ƒ์„ฑํ•˜๋ฉด ๊ธฐ๋ณธ์ ์œผ๋กœ eslint-config-react-app ์ด๋ผ๋Š” eslint ์„ค์ •์ด ์„ธํŒ…๋˜์–ด์žˆ๋‹ค.

esling-plugin-*

plugin์€ ๋ฃฐ์„ ์ •์˜ํ•œ ๊ฒƒ์œผ๋กœ, ์˜ˆ๋ฅผ ๋“ค๋ฉด esling-plugin-react๋Š” ๋ฆฌ์•กํŠธ์™€ ๊ด€๋ จ๋œ ๋ฃฐ์„ ์ •์˜ํ•œ ํŒจํ‚ค์ง€ ์ด๋‹ค.

{
  "plugins":["react"]
}

์ด๋ ‡๊ฒŒ๋งŒ ๋„ฃ์–ด๋‘๋ฉด ์•„๋ฌด๋Ÿฐ ๋™์ž‘๋„ ํ•˜์ง€ ์•Š๋Š”๋‹ค. ์ด ์ƒํƒœ๋Š” eslint-plugin-react์— ์กด์žฌํ•˜๋Š” ๋ฃฐ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๊ฒƒ์ด๋‹ค! ๋งŒ์•ฝ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ์ •์˜ํ•ด์•ผํ•จ

{
  "plugins":["react"],
  "rules":{
  	"react/jsx-uses-react":"error",
    "react/jsx-uses-vars":"error
  }
}

์ด๋Ÿฐ์‹์œผ๋กœ ๋งค๋ฒˆ ๋ชจ๋‘” ๋ฃฐ์— ๋Œ€ํ•ด ๋ถ„์„ํ•˜๊ณ  ํŒŒ์•…ํ•ด์„œ ์ผ์ผํžˆ ์ž‘์„ฑํ•˜๊ธฐ์—๋Š” ๋„ˆ๋ฌด ๊ท€์ฐฎ๋‹ค. ๋•Œ๋ฌธ์— ๋Œ€๋ถ€๋ถ„์˜ ํ”Œ๋Ÿฌ๊ทธ์ธ์€ recommened๋‚˜ strict, all ๋“ฑ์˜ ์ž์ฒด ์„ค์ •์„ ์ œ๊ณตํ•œ๋‹ค.
eslint-plugin-react์˜ ๊ฒฝ์šฐ recommended์™€ all ๋‘๊ฐ€์ง€์˜ config๋ฅผ ์ œ๊ณตํ•˜๋Š”๋ฐ ์•„๋ž˜์™€ ๊ฐ™์ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

{
  "extends":["plugin:react/recommended"]
}

์œ„์˜ ์„ค์ •์ด ์ด๋ฏธ pluging ์„ ์–ธ์„ ํฌํ•จํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋”ฐ๋กœ eslint์— ์ ์ง€ ์•Š์•„๋„๋œ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ recommended config๊ฐ€ ์ด๋Ÿฌํ•œ ํ˜•ํƒœ๋ฅผ ์ทจํ•˜๊ณ  ์žˆ๋‹ค.

esling-config-*

์ด๋Ÿฌํ•œ esling-plugin- ํŒจํ‚ค์ง€๋“ค์ด๋‚˜ ๋ฃฐ๋“ค์„ ๋ชจ์•„์„œ ์„ค์ •์œผ๋กœ ๋งŒ๋“  ๊ฒƒ์ด eslint-config- ํŒจํ‚ค์ง€๋‹ค. ์˜ˆ๋ฅผ๋“ค๋ฉด, esling-config-airbnb๋Š” eslint, eslint-plugin-import, eslint-plugin-react, eslint-plugin-react-hooks, eslint-plugin-jsx-a11y์˜ ๋ฃฐ๋“ค์„ ์กฐํ•ฉํ•œ ์„ค์ • ํŒจํ‚ค์ง€ ์ด๊ณ  ์•„๋ž˜์™€ ๊ฐ™์ด ์ •์˜ํ•ด์„œ ์‚ฌ์šฉํ•œ๋‹ค.

{
  "extends":["airbnb"]
}

eslint-plugin- ํŒจํ‚ค์ง€์˜ ์„ค์ •์€ extends์—์„œ plugin:ํŒจํ‚ค์ง€๋„ค์ž„/์„ค์ •๋„ค์ž„์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ eslint-confing- ํŒจํ‚ค์ง€์˜ ์„ค์ •์€ ๋ฐ”๋กœ *๋ฅผ ์จ์ฃผ๊ธฐ๋งŒ ํ•˜๋ฉด ๋œ๋‹ค. ํ”Œ๋Ÿฌ๊ทธ์ธ ํŒจํ‚ค์ง€๋ฅผ plugins์— ๋‹จ์ถ•์–ด๋กœ ์“ฐ๋˜ ๊ฒƒ๊ณผ ๋™์ผํ•˜๋‹ค.

parser

์ฝ”๋“œ๋ฅผ ๋ถ„์„ํ•˜๊ธฐ ์œ„ํ•œ ํŒŒ์‹ฑํˆด, ๊ธฐ๋ณธ๊ฐ’์€ espree์ด๋‹ค. ํ•˜์ง€๋งŒ ๋ณดํ†ต js์›Œํฌ์ŠคํŽ˜์ด์Šค์—์„œ๋Š” @babel/eslint-parser๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ts์›Œํฌ์ŠคํŽ˜์ด์Šค์ธ ๊ฒฝ์šฐ @typescript-eslint/parser๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
plugin:@typescript-eslint/recommended๋ฅผ ํฌํ•จ์‹œํ‚ค๋ฉด @typescript-eslint/parser๊ฐ€ ์ž๋™์œผ๋กœ ํฌํ•จ๋œ๋‹ค.

	"parser":"@typescript-eslint/parser"

ESLint๊ฐ€ formatting rules๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๊ฒƒ์„ ์ค‘๋‹จํ•  ์ˆ˜ ์žˆ๋‹ค

env

์‚ฌ์ „ ์ •์˜๋œ ์ „์—ญ ๋ณ€์ˆ˜๋ฅผ ์ œ๊ณตํ•œ๋‹ค. node ํ™˜๊ฒฝ์ธ ์›Œํฌ์ŠคํŽ˜์ด์Šค๋ฉด node:true๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผํ•˜๊ณ , ์›น ํ™˜๊ฒฝ์ด๋ผ๋ฉด browser:true, es6:true ๋“ฑ์„ ์ถ”๊ฐ€ํ•ด์•ผํ•œ๋‹ค. files๋‚˜ overrides๋ฅผ ์‚ฌ์šฉํ•ด์„œ ํŒŒ์ผ ํŒจํ„ด๋‹จ์œ„๋กœ ์ ์šฉํ•  ์ „์—ญ๋ณ€์ˆ˜๋ฅผ ๋‚˜๋ˆŒ ์ˆ˜๋„ ์žˆ๋‹ค

What is Prettier

์ฝ”๋“œ๋ฅผ ๋ณด๊ธฐ์ข‹๊ฒŒ ํฌ๋งทํŒ… ํ•ด์ค€๋‹ค. ์„ค์ •ํŒŒ์ผ์— ์ •ํ•ด๋‘” ๊ทœ์น™์œผ๋กœ ์ฝ”๋“œ ๊ตฌ์กฐ๋ฅผ ์™„์ „ํžˆ ์ƒˆ๋กœ ์ž‘์„ฑํ•ด์คŒ!

์ฐธ๊ณ 
https://yrnana.dev/post/2021-09-02-eslint
https://javascript.plainenglish.io/setting-eslint-and-prettier-on-a-react-typescript-project-2021-22993565edf9

profile
์žผ๋‚˜๊ฒŒ ์ฝ”๋”ฉํ•˜๋ฉด์„œ ์‚ด๊ณ  ์‹ถ์–ด์š” ^O^/

2๊ฐœ์˜ ๋Œ“๊ธ€

comment-user-thumbnail
2023๋…„ 3์›” 28์ผ

๋•๋ถ„์— ์ž˜ ์„ธํŒ…ํ–ˆ์–ด์š”~
๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค ใ…Žใ…Ž

1๊ฐœ์˜ ๋‹ต๊ธ€