๋ณธ๋ฌธ์œผ๋กœ ๊ฑด๋„ˆ๋›ฐ๊ธฐ

Project: ๐Ÿšฉcodefolio - ESlint, prettierrc ์„ค์ •ํ•˜๊ธฐ / as-is to-be : 2

ยท ์•ฝ 4๋ถ„
Seung hyo, Lee
Front End Engineer @ Assistfit
๐ŸŽฏ๋ชฉ์ 

์ฝ”๋“œ ์ปจ๋ฒค์…˜ ์œ ์ง€๋ฅผ ์œ„ํ•ด ESLint์™€ prettier๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ดˆ๊ธฐ์„ธํŒ…, ๊ณผ์ • ๊ธฐ๋ก

๐Ÿคข ์˜ค๋ฅ˜ ํ•ด๊ฒฐ (as-is to-be)
  • ESLint function declaration
  • ESLint ์ ์šฉ์‹œ ๋‹จ์–ธ๋ฌธ (!) ๊ฒฝ๊ณ  ๋ฉ”์„ธ์ง€

1. ESLintโ€‹

๋Œ€๋ถ€๋ถ„์˜ ๊ฐœ๋ฐœ์ž๋“ค์€ eslint๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ , prettier์— ์˜์กดํ•˜์—ฌ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•œ๋‹ค.

eslint ๋Š” ์ฝ”๋“œ ํ€„๋ฆฌํ‹ฐ๋ฅผ ๋ณด์žฅํ•˜๋„๋ก ๋„์™€์ค€๋‹ค.

์˜ˆ์‹œ๋กœ๋Š” react์—์„œ ์ปดํฌ๋„ŒํŠธ ์„ ์–ธ์„ arrow function ์œผ๋กœ ์ง€์ •ํ•˜๊ณ , ์–ด๋–ค ํŒŒ์ผ์—์„œ ์ผ๋ฐ˜ํ•จ์ˆ˜๋กœ ๋˜์–ด์žˆ๋‹ค๋ฉด, ์—๋Ÿฌ๋ฅผ ๋ฐœ์ƒ์‹œ์ผœ ์ฝ”๋“œ ์ปจ๋ฒค์…˜์ด ํ†ต์ผ์ด ๋˜๋„๋ก ์œ ๋„ํ•œ๋‹ค.

์ด ๊ณผ์ •์€ prettier ์ฒ˜๋Ÿผ 'ํŒŒ์ผ ์ €์žฅ' ํ–ˆ์„ ๋•Œ์™€๋Š” ๋‹ค๋ฅด๊ฒŒ lint ๋ฅผ run ํ•ด์•ผ ๋™์ž‘ํ•œ๋‹ค.

npm install -D eslint
# or
yarn add -D eslint

์œ„ ๋ช…๋ น์–ด๋กœ ํ”„๋กœ์ ํŠธ ๋‚ด์— ๋ฆฐํŠธ๋ฅผ ์„ค์น˜ํ•ด์ฃผ๊ณ  ๋ฆฐํŠธ ํ™˜๊ฒฝ์„ ์„ธํŒ…ํ•ด์ฃผ๋Š” ๋ชจ๋“ˆ์„ ์ž‘์„ฑํ•ด์ค˜์•ผ ํ•œ๋‹ค.(.prettierrc ์„ธํŒ… ์ฒ˜๋Ÿผ)

ํ•˜์ง€๋งŒ, ๋ชจ๋“  ํ™˜๊ฒฝ(rules)์„ ์„ค์น˜ํ•ด์ฃผ๋Š” ๋ฒˆ๊ฑฐ๋กœ์›€์„ ์ค„์ด๊ธฐ ์œ„ํ•ด ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์„ค์น˜ํ•˜๋Š”๊ฒŒ ๋น ๋ฅด๋‹ค.

์šฐ๋ฆฌ๋Š” ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋ฏ€๋กœ typescript-eslint๋ฅผ ์ ์šฉํ•˜๊ธฐ๋กœ ํ–ˆ๋‹ค.

typescript-eslint

npm install -D eslint-config-airbnb-typescript @typescript-eslint/eslint-plugin @typescript-eslint/parser

๊ทธ๋ฆฌ๊ณ  ๊ฐ€์žฅ ํ•ต์‹ฌ์ด ๋˜๋Š” 2๊ฐ€์ง€๊ฐ€ ์žˆ๋‹ค.

eslint๋งŒ ์„ค์น˜ํ–ˆ๋‹ค๊ณ  ํ•ด์„œ ๋ฐ”๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, eslint extension์„ ๋ฌด์กฐ๊ฑด ์„ค์น˜๋ฅผ ํ•ด์ฃผ์–ด์•ผ ํ•˜๊ณ ,

ํ”„๋กœ์ ํŠธ init์„ ํ•˜๋Š” ์ƒํ™ฉ์ด๋ผ๋ฉด, ์ฆ‰ first commit ์ด๋ผ๋ฉด .eslintrc.json ํŒŒ์ผ์— ํ™˜๊ฒฝ ์„ค์ •์„ ํ•ด์ค˜์•ผ ํ•œ๋‹ค.

.eslintrc.json
{
"parser": "@typescript-eslint/parser",
"env": {
"browser": true,
"es2021": true,
"node": true
},
"extends": [
"airbnb",
"airbnb-typescript",
"airbnb/hooks",
"next/core-web-vitals",
"plugin:@typescript-eslint/recommended",
"plugin:prettier/recommended",
"prettier"
],
"overrides": [],
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module",
"project": "./tsconfig.json",
"createDefaultProgram": true
},
"plugins": ["react", "@typescript-eslint", "prettier"],
"rules": {
"react/jsx-props-no-spreading": 0,
"react/function-component-definition": [
2,
{ "namedComponents": "arrow-function" }
]
}
}

eslint plugin ์œผ๋กœ ์œ ๋ช…ํ•œ airbnb ๊ทœ์น™์„ ์ ์šฉํ•ด์ฃผ์—ˆ๊ณ , ์ข…์† ํŒจํ‚ค์ง€ ๋ชฉ๋ก๋“ค์„ ๊ฐ™์ด ๋„ฃ์—ˆ๋‹ค.

๋˜ํ•œ rules ์—์„œ๋Š” ์ทจํ–ฅ์— ๋งž๊ฒŒ ๊ทœ์น™์„ ์„ค์ •ํ•˜๋Š”๋ฐ, ์šฐ๋ฆฌ๋Š” 2๊ฐ€์ง€๋ฅผ ์ ์šฉํ–ˆ๋‹ค.

"react/function-component-definition" ์ด ๋ถ€๋ถ„์€ ์—๋Ÿฌ๋กœ ์ธํ•ด ์•„๋ž˜ ์ƒ์„ธํžˆ ๊ธฐ๋กํ•˜๊ฒ ๋‹ค. ์œ„ ์˜ˆ์‹œ์—์„œ ์„ค๋ช…ํ•œ ๋ถ€๋ถ„์ฒ˜๋Ÿผ ์ปดํฌ๋„ŒํŠธ๋“ค์˜ ๊ธฐ๋ณธ ๊ตฌ์กฐ์ธ function ์„ ์–ธ ๋ฐฉ์‹์„ arrow-function ์œผ๋กœ ์ง€์ •ํ•ด ์ฃผ์—ˆ๋‹ค.


2. prettierโ€‹

ํ”„๋ฆฌํ‹ฐ์–ด ๋ณดํ†ต ๊ฐœ์ธ ์ฝ”๋“œ์—๋„ ๋งŽ์ด๋“ค ์ ์šฉํ•˜๋Š” extension ์ด๊ธฐ์— ์ž์„ธํ•œ ์„ค๋ช…์€ ์ƒ๋žต ํ•˜๊ฒ ๋‹ค.

์šฐ๋ฆฌ๋Š” eslint์™€ prettier๋ฅผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๊ธฐ์— ๊ทœ์น™๋“ค์ด ์ถฉ๋Œ๋จ์œผ๋กœ ์˜์กด์„ฑ ํŒจํ‚ค์ง€๋“ค์„ ์„ค์น˜ํ•ด์•ผ ํ–ˆ๋‹ค.

npm install -D prettier eslint-plugin-prettier eslint-config-prettier

.prettierrc.yml ํŒŒ์ผ์—๋Š”

.prettierrc.yml
arrowParens: "always"
bracketSpacing: true
jsxBracketSameLine: false
jsxSingleQuote: false
printWidth: 80
proseWrap: "always"
quoteProps: "as-needed"
semi: true
doubleQuote: true
tabWidth: 2
trailingComma: "es5"
useTabs: false

์ด๋Ÿฌํ•œ ํ˜•์‹์œผ๋กœ ์ฝ”๋“œ์˜ ์Šคํƒ€์ผ์„ ๋งž์ท„๋‹ค.


+ ์˜ค๋ฅ˜ ํ•ด๊ฒฐ : Function component is not a function declarationโ€‹

as-is

const DetailPage: NextPage = () => {
return <div>.</div>;
}; // Function component is not a function declaration

export default DetailPage;
./pages/profile/[[...userId]].tsx
3:31 Error: Function component is not a function declaration react/function-component-definition

./pages/profile/detail/[id].tsx
3:37 Error: Function component is not a function declaration react/function-component-definition

./pages/profile/edit-profile/[id].tsx
3:35 Error: Function component is not a function declaration react/function-component-definition

info - Need to disable some ESLint rules? Learn more here: https://nextjs.org/docs/basic-features/eslint#disabling-rules
error Command failed with exit code 1.

์œ„ ์˜ค๋ฅ˜๋Š” eslint์˜ ํ™˜๊ฒฝ์—์„œ function ์„ ์–ธ์ด ๋˜์ง€ ์•Š์•˜๋‹ค๋Š” ๋œป์œผ๋กœ .eslintrc.json ํŒŒ์ผ์˜ rules์—์„œ ์ปดํฌ๋„ŒํŠธ๋“ค์˜ ๊ธฐ๋ณธ ๊ตฌ์กฐ์ธ function ์„ ์–ธ ๋ฐฉ์‹์„ arrow-function ์œผ๋กœ ์ง€์ •ํ•ด ์ฃผ์–ด ํ•ด๊ฒฐํ•˜์˜€๋‹ค.

to-be

$ yarn lint
โœ” No ESLint warnings or errors
โœจ Done in 3.76s.

+ ์˜ค๋ฅ˜ ํ•ด๊ฒฐ : Forbidden non-null assertionโ€‹

as-is

lib/supabase.ts
import { createClient } from "@supabase/supabase-js";

const options = {
auth: {
autoRefreshToken: true,
persistSession: true,
detectSessionInUrl: true,
},
};

const supabase = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!, // Forbidden non-null assertion
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!, // Forbidden non-null assertion
options
);

export default supabase;
./lib/supabase.ts
12:3 Warning: Forbidden non-null assertion. @typescript-eslint/no-non-null-assertion
13:3 Warning: Forbidden non-null assertion. @typescript-eslint/no-non-null-assertion

๋‹จ์–ธ ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•ด ๋ฟœ๋Š” ๊ฒฝ๊ณ  ๋ฉ”์„ธ์ง€์ด๋‹ค. ์œ„ ๋ถ€๋ถ„์€ api key ์„ ์–ธ์œผ๋กœ ์ธํ•œ ์—๋Ÿฌ๋ฅผ ์šฐํšŒํ•  ๋ฐฉ๋ฒ•์ด ๋”ฑํžˆ ๋– ์˜ค๋ฅด์ง€ ์•Š์•˜์œผ๋‚˜ ๊ฐ„๋‹จํ•˜๊ฒŒ eslint ๊ตฌ๋ฌธ์„ ์ถ”๊ฐ€ํ•ด ํ•ด๋‹น ํŽ˜์ด์ง€์—์„œ๋Š” eslint๋ฅผ ์ ์šฉํ•˜์ง€ ์•Š๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ ํ•ด๊ฒฐํ–ˆ๋‹ค.

to-be

lib/supabase.ts
/* eslint-disable */

import { createClient } from "@supabase/supabase-js";
// ...
$ yarn lint
โœ” No ESLint warnings or errors
โœจ Done in 3.07s.

๋ฌด์‹œํ•˜๊ณ ์ž ํ•˜๋Š” ํŒŒ์ผ ๋งจ ์œ—์ค„์— /* eslint-disable */ ์ถ”๊ฐ€ํ•ด ์ค€๋‹ค. ํŒŒ์ผ ํ•˜๋‚˜ ์ „์ฒด๋ฅผ ๋ฌด์‹œํ•˜๊ณ  ์‹ถ์„ ๋•Œ ์‚ฌ์šฉ

/* eslint-disable */

์ตœ์ข… ์ •๋ฆฌ
  1. eslint๋Š” ์ฝ”๋“œ ํ€„๋ฆฌํ‹ฐ, ์ฝ”๋“œ ์ปจ๋ฒค์…˜์„ ์œ„ํ•ด ์‚ฌ์šฉ
  2. prettier๋Š” ์ฝ”๋“œ ์Šคํƒ€์ผ์„ ์œ„ํ•ด ์‚ฌ์šฉ('' space ; ์ค„ ๋งž์ถค ๋“ฑ )
  3. eslint : function declaration ์€ rules ์— "react/function-component-definition" ์„ค์ •ํ•˜์—ฌ ํ•ด๊ฒฐ
  4. eslint : ์ ์šฉ ์ œ์™ธํ•  ํŒŒ์ผ ์ตœ ์ƒ๋‹จ์— /* eslint-disable */ ์ถ”๊ฐ€