๐ŸŽ Gift MBTI - 1. Next.js ํ”„๋กœ์ ํŠธ ์„ธํŒ…, ESLint(airbnb), Prettier ์„ค์ •

zamanยท2022๋…„ 9์›” 18์ผ
0

Toy Projects

๋ชฉ๋ก ๋ณด๊ธฐ
1/6
post-thumbnail

์˜ค๋Š˜๋ถ€ํ„ฐ ์•ฝ 3์ฃผ๊ฐ„ ์›น ๋””์ž์ด๋„ˆ์™€ ํ˜‘์—…์œผ๋กœ ์ž‘์€ ํ† ์ด ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค
ํ”„๋กœ์ ํŠธ ๊ทœ๋ชจ๊ฐ€ ์ž‘์•„์„œ ๊ทธ ๋™์•ˆ ์‚ฌ์šฉํ•ด๋ณด๊ณ  ์‹ถ๋˜ next.js์™€ redux-toolkit์„ ์—ฐ์Šตํ•ด๋ณด๋Š” ์ข‹์€ ๊ธฐํšŒ๊ฐ€ ๋  ๊ฒƒ ๊ฐ™๋‹ค ๐Ÿ‘


1. ํ”„๋กœ์ ํŠธ ์„ธํŒ…

์‚ฌ์šฉ ์Šคํƒ

: Next.js, Typescript, redux-toolkit, emotion

์‚ฌ์šฉ ํˆด

ํ˜‘์—… ๋ฐ ํ”„๋กœ์ ํŠธ ๊ด€๋ฆฌ I Github
์ปค๋ฎค๋‹ˆ์ผ€์ด์…˜ I Jira
UI, ํ™”๋ฉด๊ตฌ์„ฑ I Figma (๋””์ž์ด๋„ˆ์™€ ํ˜‘์—…!)
ํšŒ์˜ I ๊ฒŒ๋”ํƒ€์šด

Next.js

Next.js๋ž€?
: React๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœํ•˜๋Š” SSR(Server Side Rendering) ํ”„๋ ˆ์ž„์›Œํฌ
cf) React๋Š” CSR(Client Side Rendering)

  • auto-routing
    : pages ํด๋”์—์„œ ์ƒ์„ฑํ•œ tsx(jsx) ํŒŒ์ผ์˜ ๊ฒฝ๋กœ ๊ทธ๋Œ€๋กœ url ์˜ path๊ฐ€ ๋จ
  • pre-rendering
    : pre-rendering๋œ HTML ํŒŒ์ผ์„ ๋ฐ›๊ฒŒ ๋จ(SEO์— ์œ ๋ฆฌ)
  • code splitting
    : ์›ํ•˜๋Š” ํŽ˜์ด์ง€์—์„œ ์›ํ•˜๋Š” JSํŒŒ์ผ๊ณผ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋ Œ๋”๋งํ•˜๋Š” ๊ฒƒ
    ๋ชจ๋“  ๋ฒˆ๋“ค์ด ํ•˜๋‚˜๋กœ ๋ฌถ์ด์ง€ ์•Š๊ณ  ๋‚˜๋‰˜์–ด ํšจ์œจ์„ฑ โฌ†๏ธ, ๋กœ๋”ฉ ์‹œ๊ฐ„ ๊ฐœ์„  ๊ฐ€๋Šฅ

create app and start!

npx create-next-app@latest --typescript
npm run dev

2. ESLint ๏น’Prettier ์„ค์ •

eslint์™€ prettier ์„ค์ •์€ ์ •๋‹ต์ด ์—†๋‹ค. ๊ทธ๋ƒฅ ์‚ฌ์šฉ์ž๊ฐ€ ํŽธํ•œ๋Œ€๋กœ ํŽธ์ง‘ํ•ด์„œ ์‚ฌ์šฉํ•˜๋ฉด๋œ๋‹ค.

ESLint
: Ecma Script Lint
Ecma์—์„œ ๋งŒ๋“  ํ‘œ์ค€ JS์— ๋”ฐ๋ผ ๋ฌธ๋ฒ• ์—๋Ÿฌ๋ฅผ ํ‘œ์‹œํ•ด์ฃผ๋Š” ๋„๊ตฌ๋กœ ๋ณด๋‹ค ์ข‹์€ ํ’ˆ์งˆ์˜ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ธฐ ์œ„ํ•œ ๊ฐ€์ด๋“œ
โœจ ์—๋Ÿฌ์™€ ์ฝ”๋”ฉ ์Šคํƒ€์ผ์„ ์žก์•„์ฃผ๊ธฐ ๋•Œ๋ฌธ์— ํ˜‘์—…ํ•  ๋•Œ ์œ ๋ฆฌ

Prettier
๋ชจ๋“  ์ฝ”๋“œ๊ฐ€ ์ผ๊ด€๋œ ์Šคํƒ€์ผ์„ ์ค€์ˆ˜ํ•˜๋„๋ก ๋งŒ๋“ค์–ด์ฃผ๋Š” ๋„๊ตฌ
โœจ ์ €์žฅ ์‹œ ์ฝ”๋“œ ํฌ๋ฉง
โœจ ์‹œ๊ฐ„,์—๋„ˆ์ง€ ์ ˆ์•ฝ ๊ฐ€๋Šฅ ์งฑํŽธํ•จ

์„ค์น˜ํ•  ๋• yarn์ด๋‚˜ npm ์ค‘ ํŽธํ•œ๊ฑธ๋กœ ์„ค์น˜ํ•˜๋ฉด ๋˜๋Š”๋ฐ ํ˜ผ์šฉํ•˜๋ฉด ์•ˆ์ข‹๋‹ค๊ณ ํ•˜๋‹ˆ ํ•œ๋†ˆ๋งŒ ์กฐ์ง€์ž

ESLint

eslint install

 yarn add -D eslint @typescript-eslint/eslint-plugin @typescript-eslint/parser 

์ด๊ฑธ ์‚ฌ์šฉํ•ด๋„ ๋˜๊ณ 

npm install -D eslint-config-airbnb-typescript

์•„๋‹ˆ๋ฉด ์ฒ˜์Œ๋ถ€ํ„ฐ ์ด๋ ‡๊ฒŒ ์„ค์น˜ํ•ด๋„ ๋จ

yarn add  --save-dev typescript eslint-config-airbnb-typescript @typescript-eslint/eslint-plugin @typescript-eslint/parser

์ฐธ๊ณ ํ•œ ๊ธ€

airbnb

npx install-peerdeps --dev eslint-config-airbnb 

.eslintrc.json

{
  "env": {
    "browser": true,
    "node": true
  },
  "parser": "@typescript-eslint/parser",
  "extends": [
    "eslint:recommended",
    "plugin:react/recommended",
    "airbnb",
    "plugin:prettier/recommended",
    "plugin:@typescript-eslint/recommended"
  ],
  "settings": {
    "react": {
      "version": "detect"
    },
    "import/resolver": {
      "node": {
        "extensions": [".js", ".jsx", ".ts", ".tsx"]
      }
    }
  },
  "parserOptions": {
    "ecmaFeatures": {
      "jsx": true
    },
 	"ecmaVersion": "latest",
    "sourceType": "module"
  },
  "plugins": ["react", "@typescript-eslint", "react-hooks", "prettier"],
  "rules": {
    "react/react-in-jsx-scope": 0,
    "react/jsx-filename-extension": ["warn", { "extensions": [".tsx"] }],
    "react/jsx-props-no-spreading": 0,
    "react/function-component-definition": [
      2,
      {
        "namedComponents": "arrow-function",
        "unnamedComponents": "arrow-function"
      }
    ]
  },
  "globals": {
    "React": "writable"
  }
}

rules

์ผ๋‹จ defaul๋กœ ๋งŒ๋“ค์–ด์ง„ ์นœ๊ตฌ๋“คํ•œํ…Œ ๋ฐœ์ƒํ•œ ์—๋Ÿฌ ์œ„์ฃผ๋กœ ๊บผ์คฌ๋‹ค. ์•„๋งˆ ํ•˜๋‹ค๋ณด๋ฉด ๋” ์ˆ˜์ •ํ•˜๊ฒŒ ๋  ๊ฒƒ ๊ฐ™์€๋ฐ ๊ทธ๋•Œ๋งˆ๋‹ค ๊ธฐ๋ก ใ„ฑใ„ฑ

0์ด๋ฉด rule ์ ์šฉ ใ„ดใ„ด, 1์ด๋ฉด ์ ์šฉ ใ…‡ใ…‡
๐Ÿ›‘ Missing file extension "ts" import/extensions ์—๋Ÿฌ
airbnb rule๋ฅผ ํ™•์žฅํ•˜๋ฉด ์ด๊ฑฐ ์—†์ด๋„ ts ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค!

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

๐Ÿ›‘ Next๋Š” React ์ž๋™ import, ์จ์ฃผ์ง€ ์•Š์•„๋„ ๋จ
โœจ "react/react-in-jsx-scope": 0,

๐Ÿ›‘ JSX not allowed in files with extension '.tsx'
โœจ "react/jsx-filename-extension": ["warn", { "extensions": [".tsx"] }],

๐Ÿ›‘ props spreading is not allowed
โœจ "react/jsx-props-no-spreading": 0

๐Ÿ›‘ ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ ๋ฐฉ์‹ ์„ ์–ธ, arrow function์œผ๋กœ
โœจ "react/function-component-definition": [ 2, { "namedComponents": "arrow-function", "unnamedComponents": "arrow-function" } ]

Prettier

prettier install

 yarn add  -D prettier eslint-config-prettier eslint-plugin-prettier

.prettierrc

{
  "singleQuote": true,
  "semi": false,
  "useTabs": false,
  "tabWidth": 2,
  "trailingComma": "all",
  "printWidth": 80,
  " arrowParens": "avoid",
  "bracketSpacing": true
}

๐Ÿค” "singleQuote": true
๐Ÿ™‹โ€โ™€๏ธ ๋ฌธ์ž์—ด ์ž‘์€ ๋”ฐ์˜ดํ‘œ cf) false: ํฐ ๋”ฐ์˜ดํ‘œ

๐Ÿค” "semi": false
๐Ÿ™‹โ€โ™€๏ธ ์„ธ๋ฏธ์ฝœ๋ก  ์‚ฌ์šฉ์—ฌ๋ถ€

๐Ÿค” "useTabs": false
๐Ÿ™‹โ€โ™€๏ธ ํƒญ ๋Œ€์‹  ์ŠคํŽ˜์ด์Šค

๐Ÿค” "tabWidth": 2
๐Ÿ™‹โ€โ™€๏ธ ๋“ค์—ฌ์“ฐ๊ธฐ 2์นธ

๐Ÿค” ""trailingComma": "all"
๐Ÿ™‹โ€โ™€๏ธ ๊ฐ์ฒด๋‚˜ ๋ฐฐ์—ด ๋“ฑ์— ๋งจ ๋งˆ์ง€๋ง‰์—๋„ ์ฝค๋งˆ

๐Ÿค” "printWidth": 80
๐Ÿ™‹โ€โ™€๏ธ ์ค„ ๋ฐ”๊ฟˆ ํ•  ํญ ๊ธธ์ด

๐Ÿค” "arrowParens": "avoid"
๐Ÿ™‹โ€โ™€๏ธ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜์—์„œ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ํ•˜๋‚˜๋งŒ ๋ฐ›์„๋•Œ ๊ด„ํ˜ธ ์ƒ๋žต

๐Ÿค” "bracketSpacing": true
๐Ÿ™‹โ€โ™€๏ธ ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด์—์„œ ๊ด„ํ˜ธ์— ๊ณต๋ฐฑ ์‚ฝ์ž… ์—ฌ๋ถ€


โž• ์„ธ๋ฏธ์ฝœ๋ก ์„ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด!

// prettier
  "semi": true,
  
// eslint
    "prettier/prettier": 0

์ด๋ ‡๊ฒŒ ์„ค์ •์„ ๋งˆ์ณค๋‹ค
๋‚ด์ผ๋ถ€ํ„ด ๋ณธ๊ฒฉ์ ์œผ๋กœ next.js๋ฅผ ํŒŒ๋ด์•ผ์ง€ ๐Ÿ˜Ž

profile
๊ฐœ๋ฐœ์ž๋กœ ์„ฑ์žฅํ•˜๊ธฐ ์œ„ํ•œ ์•„์นด์ด๋ธŒ ๐Ÿ˜Ž

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