Project: ๐ฉcodefolio - ESlint, prettierrc ์ค์ ํ๊ธฐ / as-is to-be : 2
์ฝ๋ ์ปจ๋ฒค์ ์ ์ง๋ฅผ ์ํด ESLint์ prettier๋ฅผ ์ฌ์ฉํ์ฌ ์ด๊ธฐ์ธํ , ๊ณผ์ ๊ธฐ๋ก
- 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๋ฅผ ์ ์ฉํ๊ธฐ๋ก ํ๋ค.
npm install -D eslint-config-airbnb-typescript @typescript-eslint/eslint-plugin @typescript-eslint/parser
๊ทธ๋ฆฌ๊ณ ๊ฐ์ฅ ํต์ฌ์ด ๋๋ 2๊ฐ์ง๊ฐ ์๋ค.
eslint๋ง ์ค์นํ๋ค๊ณ ํด์ ๋ฐ๋ก ์ฌ์ฉํ ์ ์๋ ๊ฒ์ด ์๋๋ผ, eslint extension์ ๋ฌด์กฐ๊ฑด ์ค์น๋ฅผ ํด์ฃผ์ด์ผ ํ๊ณ ,
ํ๋ก์ ํธ init์ ํ๋ ์ํฉ์ด๋ผ๋ฉด, ์ฆ first commit ์ด๋ผ๋ฉด .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 ํ์ผ์๋
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
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
/* eslint-disable */
import { createClient } from "@supabase/supabase-js";
// ...
$ yarn lint
โ No ESLint warnings or errors
โจ Done in 3.07s.
๋ฌด์ํ๊ณ ์ ํ๋ ํ์ผ ๋งจ ์์ค์ /* eslint-disable */ ์ถ๊ฐํด ์ค๋ค. ํ์ผ ํ๋ ์ ์ฒด๋ฅผ ๋ฌด์ํ๊ณ ์ถ์ ๋ ์ฌ์ฉ
/* eslint-disable */
- eslint๋ ์ฝ๋ ํ๋ฆฌํฐ, ์ฝ๋ ์ปจ๋ฒค์ ์ ์ํด ์ฌ์ฉ
- prettier๋ ์ฝ๋ ์คํ์ผ์ ์ํด ์ฌ์ฉ(
''space;์ค ๋ง์ถค ๋ฑ ) - eslint : function declaration ์ rules ์
"react/function-component-definition"์ค์ ํ์ฌ ํด๊ฒฐ - eslint : ์ ์ฉ ์ ์ธํ ํ์ผ ์ต ์๋จ์
/* eslint-disable */์ถ๊ฐ
