Post

TailwindCSS ์„ธํŒ…(1) - ESlint Plugin

๐Ÿ“Œ์‹œ์ž‘ํ•˜๋ฉฐ

Next.js์—์„œ TailwindCSS ์ด์šฉํ•ด ์Šคํƒ€์ผ๋ง์„ ํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ•˜๊ณ , ํ•„์š”ํ•œ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์„ค์น˜ํ–ˆ๋‹ค. ํ•˜์ง€๋งŒ ์˜ˆ์ƒ๋Œ€๋กœ ์ž‘๋™ํ•˜์ง€ ์•Š๊ฑฐ๋‚˜ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ์—ˆ๋‹ค. TailwindCSS๋Š” ์ข…์ข… ์‚ฌ์šฉํ•  ๊ฒƒ ๊ฐ™์œผ๋‹ˆ ์ด๋ฒˆ ๊ธฐํšŒ์— ์–ด๋–ค ์˜ค๋ฅ˜๊ฐ€ ์žˆ๋Š”์ง€ ์ •๋ฆฌํ•˜๊ณ , ๋‚˜๋ฆ„์˜ ์„ธํŒ… ๊ณผ์ •์„ ์ •๋ฆฌํ•ด๋ณด๊ณ ์ž ํ•œ๋‹ค.

์ด ๊ธ€์€ ์•„๋ž˜์™€ ๊ฐ™์ด ์ด์–ด์ง‘๋‹ˆ๋‹ค.

โœ… ํŠน์ • ํด๋” ํ•˜์œ„ ํŒŒ์ผ์—์„œ TailwindCSS ์ž‘๋™ ์•ˆํ•  ๋•Œ

next13์—์„œ app ํด๋”๋ฅผ ์‚ฌ์šฉํ•ด component ํด๋”๋ฅผ ๋งŒ๋“ค์—ˆ์œผ๋‚˜ component ํด๋”์—์„œ ์•„๋ฌด๋ฆฌ tailwind ํด๋ž˜์Šค๋ฅผ ์ž‘์„ฑํ•ด๋„ ์ œ๋Œ€๋กœ ์ž‘๋™ํ•˜์ง€ ์•Š์•˜๋‹ค.

1
2
3
4
5
โ”œโ”€โ”€ app/
โ”‚   โ””โ”€โ”€ page.tsx
โ”‚
โ””โ”€โ”€ component/
    โ””โ”€โ”€ header.tsx

์•Œ๊ณ  ๋ณด๋‹ˆ tailwind.config.ts ํŒŒ์ผ์— ์ ํžŒ ๊ฒฝ๋กœ๊ฐ€ component๊ฐ€ ์•„๋‹ˆ๋ผ components์—ฌ์„œ ๋ฐœ์ƒํ•œ ๋ฌธ์ œ์˜€๋‹ค. ๋‘˜ ์ค‘ ํ•˜๋‚˜์˜ ์ด๋ฆ„์„ ๋ฐ”๊ฟ”์ฃผ๋ฉด ๋œ๋‹ค. ๋‚˜๋Š” components๋กœ ํด๋” ์ด๋ฆ„์„ ๋ณ€๊ฒฝํ–ˆ๋‹ค.

1
2
3
4
5
6
7
8
9
10
import type { Config } from "tailwindcss"

const config: Config = {
  content: [
    "./src/pages/**/*.{js,ts,jsx,tsx,mdx}",
    "./src/components/**/*.{js,ts,jsx,tsx,mdx}",
    "./src/app/**/*.{js,ts,jsx,tsx,mdx}",
  ],
  //์ƒ๋žต
}

โœ… eslint๊ฐ€ ์ œ๋Œ€๋กœ ์ž‘๋™ํ•˜๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ

next.js๋ฅผ ์„ค์น˜ํ•  ๋•Œ ์ž๋™์œผ๋กœ package.json์— ์ ํ˜€ ์žˆ๋Š” "lint": "next lint" ๋ฅผ ํ™œ์šฉํ•ด ํ™•์ธํ•˜๋ฉด ๋œ๋‹ค. ์ž‘์„ฑํ•œ tailwind๊ฐ€ order ๊ทœ์น™์— ๋งž์ง€ ์•Š๊ฑฐ๋‚˜, ์•Œ ์ˆ˜ ์—†๋Š” className์ธ ๊ฒฝ์šฐ warning์ด ๋ฐœ์ƒํ•จ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

1
npm run lint

ํ˜น์€ VS code์˜ ์ถœ๋ ฅ > eslint ๋ฅผ ํ™•์ธํ•ด ์ œ๋Œ€๋กœ ์ž‘๋™ํ•˜๊ณ  ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๋ฉด ๋œ๋‹ค.

โœ… Failed to load config โ€œprettierโ€ to extend from

๊ทธ๋Ÿฐ๋ฐ ์œ„์—์„œ ์ž‘๋™ํ•˜๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด npm run lint๋ฅผ ์ž‘๋™ํ•˜์ž ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค.

1
Failed to load config "prettier" to extend from.

ํ•ด๋‹น ์˜ค๋ฅ˜๋Š” ํ•„์š”ํ•œ eslint-prettier ํ”Œ๋Ÿฌ๊ทธ์ธ์ด ๋น ์ ธ์žˆ์–ด์„œ ๋ฐœ์ƒํ•œ ๊ฒƒ์ด์—ˆ๋‹ค. ์ถ”๊ฐ€์ ์œผ๋กœ ํ•„์š”ํ•œ ๋‚ด์šฉ์„ ์„ค์น˜ํ•˜์ž.

1
yarn add --dev prettier eslint-config-prettier eslint-plugin-prettier

โœ… eslint-plugin-tailwindcss

์˜คํ”ผ์…œ๋กœ ์ œ๊ณตํ•˜๋Š” prettier-plugin-tailwindcss๋ณด๋‹ค ๋” ๋งŽ์€ ๊ทœ์น™์„ ์ œ๊ณตํ•˜๋Š” ์œ ์šฉํ•œ plugin์ด๋‹ค. class ์ •๋ ฌ, ๋ณ‘ํ•ฉ, ์ž„์˜ ๊ฐ’ ์‚ฌ์šฉ ๊ธˆ์ง€, ๋™์ผ ์†์„ฑ ๋ฎ์–ด์“ฐ๊ธฐ ๊ธˆ์ง€ ๋“ฑ์„ ์ œ๊ณตํ•œ๋‹ค.

1
yarn add --dev eslint-plugin-tailwindcss

์„ค์น˜ ํ•ด ์ค€๋‹ค์Œ, eslintrc.json์— ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑํ•ด extends์™€ rules๋ฅผ ์ถ”๊ฐ€ํ•ด์ค€๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
  "extends": [
    "next/core-web-vitals",
    "prettier",
    "plugin:tailwindcss/recommended" ๐Ÿ‘ˆ
  ],
  "rules": { ๐Ÿ‘ˆ
    "tailwindcss/classnames-order": "warn",
    "tailwindcss/enforces-negative-arbitrary-values": "warn",
    "tailwindcss/enforces-shorthand": "warn",
    "tailwindcss/no-custom-classname": "warn",
    "tailwindcss/no-arbitrary-value:": "warn",
    "tailwindcss/no-contradicting-classname": "warn"
  }
}

โœ… ์ €์žฅํ•˜๋ฉด eslint ๊ทœ์น™ ์ ์šฉ๋˜๊ฒŒ ํ•˜๊ธฐ

์œ„์˜ ์˜ค๋ฅ˜๋ฅผ ํ•ด๊ฒฐํ•˜๊ณ  ๋‹ค์‹œ npm run lint๋ฅผ ํ•ด๋ณด๋ฉด ๋ฌธ์ œ๊ฐ€ ์žˆ๋Š” className์„ ์ž˜ ์žก์•„๋ƒˆ์œผ๋‚˜, ์ €์žฅํ•  ๋•Œ eslint plugin์ด ์ž๋™์œผ๋กœ ์ •๋ ฌ๋˜์ง€ ์•Š์•˜๋Š”๋ฐ, ์ด ๋ฌธ์ œ๋Š” VS code์˜ settings.json์— ์•„๋ž˜์™€ ๊ฐ™์ด ์ ์–ด ํ•ด๊ฒฐํ–ˆ๋‹ค.

1
2
3
4
5
{
  "editor.codeActionsOnSave": {
    "source.fixAll": true
  }
}

โœ… tailwindCSS

๐Ÿ“ฉ๋งˆ๋ฌด๋ฆฌ

๊ธฐ๋ณธ ์„ธํŒ…์„ ์ด๋ ‡๊ฒŒ ๋งˆ๋ฌด๋ž˜ํ•ฌ๋‹ค. ์ด์ œ tailwind ์ปค์Šคํ…€์„ ์‹œ์ž‘ํ•ด๋ณด์ž

๐Ÿ—‚๏ธ์ฐธ๊ณ  ์‚ฌ์ดํŠธ

This post is licensed under CC BY 4.0 by the author.