Skip to content

Latest commit

ย 

History

History
348 lines (253 loc) ยท 10.7 KB

ESLint & Prettier, husky & lint-staged ์ •๋ฆฌ.md

File metadata and controls

348 lines (253 loc) ยท 10.7 KB

๋ชฉ์ฐจ


ESLint

ESLint is an open source project that helps you find and fix problems with your JavaScript code. It doesn't matter if you're writing JavaScript in the browser or on the server, with or without a framework, ESLint can help your code live its best life.

  • ์ผ๊ด€์„ฑ ์žˆ๊ณ  ์—๋Ÿฌ๋ฅผ ํ”ผํ•  ์ˆ˜ ์žˆ๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ธฐ ์œ„ํ•ด์„œ ๋งŒ๋“ค์–ด์ง„ ์ฝ”๋“œ ๋ถ„์„ ํˆด
  • ์ž‘์„ฑ๋œ ์ฝ”๋“œ๋ฅผ ๋ถ„์„ํ•˜์—ฌ ๋ถˆํ•„์š”, ๋ณด์•ˆ ์œ„๋ฐฐ, ๋ฒ„๊ทธ ์—ฌ์ง€๊ฐ€ ์žˆ๋Š” ์ฝ”๋“œ๋ฅผ ์•Œ๋ฆผ
  • ์ปค์Šคํ„ฐ๋งˆ์ด์ง•์„ ํ—ˆ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํ•„์š”ํ•œ ๊ทœ์น™์„ ์„ค์ • ๊ฐ€๋Šฅ

Prettier

  • ์ฝ”๋“œ ํฌ๋งทํ„ฐ๋กœ ์Šคํƒ€์ผ์— ๋Œ€ํ•œ ์‹œ๊ฐ„ ๋ฐ ์—๋„ˆ์ง€ ์ ˆ์•ฝ
  • ์Šคํƒ€์ผ์— ๋Œ€ํ•œ ํ† ๋ก ์ด ์ค„๊ณ , ์ค‘์š”ํ•œ ๊ฐœ๋ฐœ์— ์ง‘์ค‘์ด ๊ฐ€๋Šฅ
  • ๋งŽ์€ ์–ธ์–ด๋“ค์„ ์ง€์›ํ•˜๊ณ  ์žˆ์Œ (JavaScript, TypeScript, HTML, CSS, ...)

์„ค์น˜

# eslint
$ npm install eslint --save-dev

# prettier
$ npm install prettier --save-dev

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

eslint-config-prettier

  • Prettier์™€ ์ถฉ๋Œํ•˜๋Š” ESLint ๊ทœ์น™(ํฌ๋งทํŒ…)์„ ๋น„ํ™œ์„ฑํ™”ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋˜๋Š” ESLint ๊ตฌ์„ฑ
  • ESLint๋Š” ์ฝ”๋“œ ์Šคํƒ€์ผ ๊ทœ์น™์„ ์ ์šฉํ•˜๋ฉฐ, Prettier๋Š” ์ฝ”๋“œ ์Šคํƒ€์ผ์„ ์ž๋™์œผ๋กœ ์ง€์ •
  • ESLint์— ํฌ๋งทํŒ…์— ๊ด€๋ จํ•œ ๊ทœ์น™์ด ํฌํ•จ๋˜์–ด ์žˆ์–ด Prettier์™€ ์ผ๋ถ€ ์ถฉ๋Œํ•˜๋ฏ€๋กœ eslint-config-prettier๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ˜ธํ™˜๋˜๋„๋ก ์กฐ์ •

์„ค์ •

  • ์„ค์น˜ ์™„๋ฃŒ ํ›„ ํŒ€์› ๊ฐ„ ๊ทœ์น™ ์„ค์ • ํ•„์š”

.eslintrc

  • ์•„๋ž˜ ๋ช…๋ น์–ด์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ฌธ๋‹ต ํ˜•์‹์„ ํ†ตํ•ด์„œ ๊ฐ„ํŽธํ•œ .eslintrc ์„ค์ •์ด ๊ฐ€๋Šฅ
$ npm init @eslint/config
  • root ๋””๋ ‰ํ† ๋ฆฌ์— .eslintrc ํŒŒ์ผ ์ƒ์„ฑ
  • ์ปค์Šคํ„ฐ๋งˆ์ด์ง• ํ•  ์ˆ˜ ์žˆ๋Š” ๋ถ€๋ถ„์ด ๋งŽ๊ณ  ์–ธ์–ด๋ณ„ ํ™˜๊ฒฝ๋ณ„๋กœ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์–ด ๋‹ค์†Œ ๋ณต์žกํ•จ
  • ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์ด ์ •์˜ํ•ด๋‘” config๋ฅผ ์„ค์น˜ํ•˜์—ฌ ํ™•์žฅํ•ด์„œ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅ
/* ํ•„์š”ํ•œ ๋‚ด์šฉ ๊ธฐ๋ก
 * 1. "env": {},
 * 1.1 https://eslint.org/docs/latest/use/configure/language-options
 *
 * 2. "extends": [],
 * 2.1 eslint plugin + rule์„ ์ข…ํ•ฉํ•˜์—ฌ ๋งŒ๋“  ๊ฒƒ
 * 2.2 eslint:recommended => https://eslint.org/docs/latest/rules ํ™œ์„ฑํ™” ๋ชฉ๋ก ํ™•์ธ
 * 2.3 eslint-config-{???} => https://www.npmjs.com/search?q=eslint-config ์ •์˜๋œ config ๊ฒ€์ƒ‰
 *                         => ์žฅ์ฐฉํ•  ๋•Œ eslint-config- ๋ถ€๋ถ„์„ ์ œ์™ธํ•˜๊ณ  '{}' ๋ถ€๋ถ„๋งŒ ์‚ฝ์ž…
 *                         => ex) eslint-config-airbnb ์„ค์น˜ ์‹œ - "extends": ['airbnb'],
 *
 * 3. "plugins": [],
 * 3.1 eslint ์ถ”๊ฐ€ ๋ฃฐ ๊ทœ์ • ๊ฐ€๋Šฅ => ex) eslint-plugin-react : react ๋ฃฐ ๊ทœ์ • ๊ฐ€๋Šฅ
 * 3.2 eslint-plugin-{???} => https://www.npmjs.com/search?q=eslint-plugin ์ •์˜๋œ plugin ๊ฒ€์ƒ‰
 *
 * 3. "rules": {},
 * 3.1 https://eslint.org/docs/latest/rules ๊ทœ์น™ ๋ชฉ๋ก ํ™•์ธ
 * 3.2 'off': ๊ทœ์น™ ๋น„ํ™œ์„ฑํ™”, 'warn': ๊ฒฝ๊ณ  ๋ฐœ์ƒ, 'error': ์—๋Ÿฌ ๋ฐœ์ƒ
 *
 * 5. "ignorePatterns": [],
 *
 */

// ์‚ฌ์šฉํ•˜๋ ค๊ณ  ๋งŒ๋“  eslint => `npm i eslint-config-airbnb eslint-config-prettier --save-dev` ํ•„์š”
{
  "extends": ["airbnb", "prettier"],
  "rules": {
    "no-console": ["warn", { "allow": ["warn", "error", "info"] }], // console ๊ฒฝ๊ณ 
    "no-multiple-empty-lines": "error", // ์—ฌ๋Ÿฌ ์ค„ ๊ณต๋ฐฑ ๊ธˆ์ง€
    "dot-notation": "error", // dot notation ์‚ฌ์šฉ
  }
}

.prettierrc

  • .prettierrc.ํ™•์žฅ์ž ํŒŒ์ผ์„ ๋ฃจํŠธ ๋””๋ ‰ํ† ๋ฆฌ์— ์ €์žฅ
  • .prettierignore ํŒŒ์ผ์„ ํ†ตํ•ด ์ ์šฉํ•˜์ง€ ์•Š์„ ํŒŒ์ผ ์„ค์ • ๊ฐ€๋Šฅ(option)
  • ํ™•์žฅ์ž๋Š” JSON, YAML, JS, TOML๋“ฑ ๋‹ค์–‘ํ•˜๊ฒŒ ์ง€์›
{
  "printWidth": 100,
  "tabWidth": 2,
  "semi": true,
  "singleQuote": true,
  "arrowParens": "always"
}

์‹คํ–‰

VSCode์—์„œ ์ €์žฅ๋งŒํ•ด๋„ ์‹คํ–‰๋˜๋Š” ESLint, Prettier๋ฅผ ๊ตณ์ด CLI๋กœ ์ง„ํ–‰ํ•˜๋Š” ์ด์œ ๋Š” ํŒ€์›์ด Editor ์„ค์ •์„ ๊ฑด๋“œ๋ ค์„œ ESLint, Prettier๋ฅผ ์ ์šฉํ•˜์ง€ ์•Š๋Š” ์ƒํ™ฉ์ด ์ƒ๊ธธ ์ˆ˜๋„ ์žˆ๋‹ค. ํŒ€์› ์ „์ฒด๊ฐ€ ์˜์‹์ ์œผ๋กœ ์„ค์ •์„ ํ•˜์ง€ ์•Š๋”๋ผ๋„ ESLint, Prettier๊ฐ€ ์ž๋™์œผ๋กœ ์‹คํ–‰๋  ์ˆ˜ ์žˆ๋„๋ก ์ž๋™ํ™”๋ฅผ ํ•ด๋ณด๊ณ ์ž ํ•œ๋‹ค.

Prettier ์‹คํ–‰

  • Prettier CLI
  • ์กฐ๊ฑด : ์—๋””ํ„ฐ ํฌ๋งทํŒ… ์„ค์ •(VSCode๋Š” formatOnSave) ํ•ด์ œ

ํŒŒ์ผ์„ ์ž‘์„ฑํ•˜๊ณ  ์ €์žฅํ•˜๋ฉด ์„ค์ •ํ•œ Prettier๋Œ€๋กœ ์ฝ”๋“œ๊ฐ€ ๋ฐ˜์˜๋˜์ง€ ์•Š์Œ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ์•„๋ž˜ CLI ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด์„œ Prettier๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

# ํ˜„์žฌ ์œ„์น˜์˜ ๋ชจ๋“  ํŒŒ์ผ์— prettier ์ ์šฉ
$ npx prettier .

์œ„ ๋ช…๋ น์–ด์˜ ๊ฒฐ๊ณผ๋กœ ์‹ค์ œ ํŒŒ์ผ์—๋Š” ๋ฐ˜์˜๋˜์ง€ ์•Š๊ณ , ํ„ฐ๋ฏธ๋„์— format ๋˜์—ˆ์„ ๋•Œ ์–ด๋–ค ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ฌ์ง€ ์ถœ๋ ฅ๋œ๋‹ค. ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง์ ‘ ํŒŒ์ผ์— formatting ๊ฒฐ๊ณผ๋ฅผ ๋„ฃ์–ด์„œ ์ €์žฅ์„ ํ•ด์ค˜์•ผํ•œ๋‹ค.

# formatting์„ ์ง„ํ–‰ํ•˜๊ณ  ๊ฒฐ๊ณผ๋ฅผ ํŒŒ์ผ์— ์ ์šฉ์‹œ์ผœ ์ €์žฅ
$ npx prettier --write .

ํ•˜๋‚˜์˜ ํŒŒ์ผ์„ ์ˆ˜์ •ํ•˜๊ณ  npx prettier --write . ๋ช…๋ น์„ ์ˆ˜ํ–‰ํ•˜๋ฉด ๋ณ€๊ฒฝํ•˜์ง€ ์•Š์€ ํŒŒ์ผ๊นŒ์ง€ ์žฌํฌ๋งทํŒ…๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์€ ํŒŒ์ผ๊นŒ์ง€ ํ•ด๋‹น ๋ช…๋ น์–ด๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ๋™์ž‘์€ ๋ถˆํ•„์š”ํ•˜๋‹ค.

# ๊ธฐ์กด์— ํฌ๋งทํŒ…ํ•œ ์ •๋ณด๋ฅผ ์ €์žฅ์„ ํ•˜๊ณ  ๋ฐ”๋€ ๋‚ด์šฉ๋งŒ ์ˆ˜์ •
$ npx prettier --write --cache .

์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ๋•Œ๋งˆ๋‹ค ๋ช…๋ น์–ด๋ฅผ ๊ธธ๊ฒŒ ์ณ์•ผํ•œ๋‹ค๋Š” ๋ฒˆ๊ฑฐ๋กœ์›€๋„ ์ƒ๊ธด๋‹ค. ๋ช…๋ น์–ด๋ฅผ ํƒ€์ดํ•‘ํ•˜๋Š” ๊ณผ์ •์„ ์ค„์ด๊ณ  ์‹ถ๋‹ค๋ฉด package.json์˜ scripts์— ๋‹จ์ถ•์–ด๋ฅผ ๋“ฑ๋กํ•˜๋ฉด ๋œ๋‹ค. scripts์˜ ํŠน์ง• ์ค‘ ํ•˜๋‚˜๋Š” npx ๋ช…๋ น์–ด๋ฅผ ์ œ์™ธํ•˜๋”๋ผ๋„ ์•Œ์•„์„œ node_modules๋ฅผ ํƒ์ƒ‰ํ•˜๊ณ  ์‹คํ–‰ํ•œ๋‹ค.

{
  "scripts": {
    "format": "prettier --write --cache ."
  }
}
# ์•„๋ž˜ ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด์„œ prettier๋ฅผ ์ ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ๋‹ค.
$ npm run format

ESLint ์‹คํ–‰

# ํ•ด๋‹น ๋””๋ ‰ํ† ๋ฆฌ ๋ชจ๋“  ํŒŒ์ผ eslint ๊ฒ€์‚ฌ ์‹คํ–‰
$ npx eslint .

# ๋ณ€ํ™”๊ฐ€ ์žˆ๋Š” ํŒŒ์ผ๋งŒ ๊ฒ€์‚ฌ ์‹คํ–‰
$ npx eslint --cache .

ESLint ๊ฒฝ์šฐ ์บ์‹œ ํŒŒ์ผ์ด ๋ฃจํŠธ์— .eslintcache๋กœ ์ €์žฅ๋˜๋ฉฐ Prettier์˜ ๊ฒฝ์šฐ node_modules๋‚ด์— cache ํŒŒ์ผ์ด ์ €์žฅ๋œ๋‹ค. ๋”ฐ๋ผ์„œ .eslintcacheํŒŒ์ผ์€ ๋”ฐ๋กœ .gitignore์— ๋“ฑ๋กํ•  ํ•„์š”๊ฐ€ ์žˆ๋‹ค.


๋งˆ์ฐฌ๊ฐ€์ง€๋กœ package.json์— ๋ช…๋ น์–ด๋ฅผ ๋“ฑ๋กํ•˜์—ฌ ์ž๋™ํ™”ํ•ด๋ณด์ž.

{
  "scripts": {
    "format": "prettier --write --cache .",
    "lint": "eslint --cache ."
  }
}
$ npm run lint

Husky

commit์„ ์ง„ํ–‰ํ•  ์ฝ”๋“œ๋Š” formatting, push๋ฅผ ์ง„ํ–‰ํ•  ์ฝ”๋“œ๋Š” lint๋ฅผ ์ž๋™์œผ๋กœ ์ ์šฉํ•ด๋ณด์ž.

  • Husky docs
  • Git Hook ์„ค์ •์„ ์‰ฝ๊ฒŒ ์„ค์ •ํ•ด์ฃผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
  • ํŒ€์› ๊ฐœ๊ฐœ์ธ์ด npm install ๋งŒ ์ˆ˜ํ–‰ํ•˜๋”๋ผ๋„ ์‚ฌ์ „์— ์„ค์ •ํ•œ Git Hook์„ ์ ์šฉ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.

Git Hook ๋„์ž…

  • Git์—์„œ ํŠน์ • ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๊ธฐ ์ด์ „๊ณผ ์ดํ›„์— Hook ๋™์ž‘์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๊ฒŒํ•˜๋Š” ๊ฒƒ
  • Git Hook ์„ค์ •์€ ๊นŒ๋‹ค๋กœ์šฐ๋ฉฐ, ํŒ€์›๋“ค์ด repo๋ฅผ ๋‹ค์šด๋กœ๋“œ ๋ฐ›๊ณ  ๋งค๋‰ด์–ผํ•˜๊ฒŒ ์‚ฌ์ „ ๊ณผ์ •์„ ์ˆ˜ํ–‰ํ•ด์•ผ hook ์‹คํ–‰์ด ๋ณด์žฅ
  • Husky๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํ†ตํ•ด Git Hook์„ ๊ฐ„๋‹จํ•˜๊ฒŒ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

Husky ์„ค์น˜

# ์„ค์น˜
$ npm install husky --save-dev

# ์ƒ์„ฑ๋œ pre-commit, pre-push ํŒŒ์ผ ๊ธฐ๋ฐ˜์œผ๋กœ Git hook ํ™œ์„ฑํ™”
$ npx husky install

npx husky install ๋ช…๋ น์–ด๋กœ husky์— ๋“ฑ๋ก๋œ hook์„ .git์— ์ ์šฉ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค. ํ•ด๋‹น ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜์ง€ ์•Š์œผ๋ฉด git hook์ด ์ ์šฉ๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ ๋ชจ๋“  ๊ฐœ๋ฐœ์ž๊ฐ€ ์‹คํ–‰ํ•ด์•ผ ํ•˜๋Š” ๋ช…๋ น์–ด๋‹ค.


{
  "scripts": {
    /**
     * scripts life cycle operation order
     * https://docs.npmjs.com/cli/v9/using-npm/scripts
     */
    "postinstall": "husky install"
    "format": "prettier --write --cache .",
    "lint": "eslint --cache ."
  }
}

ํด๋ก ์„ ์ง„ํ–‰ํ•œ ๊ฐœ๋ฐœ์ž๊ฐ€ npm install ๋ช…๋ น์–ด๋งŒ ์ž…๋ ฅํ•ด๋„ ์ž๋™์œผ๋กœ npx husky install์ด ์ˆ˜ํ–‰๋˜๋„๋ก postinstall๋กœ ์„ค์ •ํ•œ๋‹ค.


Git Hook ์ถ”๊ฐ€ํ•˜๊ธฐ

# ๋ช…๋ น์–ด
$ npx husky add <file> [cmd]

# commit ์ด์ „ npm run format ์ž๋™ ์‹คํ–‰
$ npx husky add .husky/pre-commit "npm run format"

# push ์ด์ „ npm run lint ์ž๋™ ์‹คํ–‰
$ npx husky add .husky/pre-push "npm run lint"

lint-staged

Husky๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ commit์„ ์ง„ํ–‰ํ•˜๊ณ  git status๋กœ ํ™•์ธํ•ด๋ณด๋ฉด modified๋œ ํŒŒ์ผ(unstaged)์ด ์—ฌ์ „ํžˆ ๋‚จ์•„์žˆ๋‹ค. git commit ๋ช…๋ น์–ด๋ฅผ ์ž…๋ ฅํ•œ ํ›„ ์–ด๋–ค ํ๋ฆ„์ด ์žˆ์—ˆ์„๊นŒ

  1. ์ปค๋ฐ‹ ์ „ ๋ณ€๊ฒฝ๋œ ํŒŒ์ผ ์กด์žฌ - staged
  2. ์ปค๋ฐ‹ ๋ช…๋ น์–ด ์‹คํ–‰ - git commit -m "์ปค๋ฐ‹๋ฉ”์‹œ์ง€"
  3. git hook pre-commit ๋™์ž‘ - npm run format
  4. prettier๋กœ ํฌ๋งทํŒ…๋œ ํŒŒ์ผ ์กด์žฌ - unstaged
  5. ์ปค๋ฐ‹ ์™„๋ฃŒ

ํฌ๋งทํŒ…๋œ ํŒŒ์ผ์„ ๋‹ค์‹œ ์ปค๋ฐ‹ํ•ด์•ผ๋˜๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฏ€๋กœ Husky๋Š” lint-staged์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•œ๋‹ค. lint-staged๋Š” staged ํŒŒ์ผ์— ํŠน์ • ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ฆ‰, ์ „์ฒด ํŒŒ์ผ์— ๋Œ€ํ•ด์„œ pre-commit hook์„ ์ˆ˜ํ–‰ํ•˜๋Š”๊ฒŒ ์•„๋‹Œ staged๋œ ํŒŒ์ผ์— pre-commit๋“ฑ์˜ hook์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๊ฒŒ๋œ๋‹ค. ๋˜ํ•œ ๋ชจ๋“  ์ฝ”๋“œ๋ฅผ ๊ฒ€์‚ฌํ•˜๋Š”๊ฒŒ ์•„๋‹Œ staged๋œ(๋ณ€๊ฒฝ๋œ) ํŒŒ์ผ๋งŒ ๊ฒ€์‚ฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ฒ€์‚ฌ ์‹œ๊ฐ„์„ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค.


๋˜ํ•œ lint-staged๋Š” staged๋œ ํŒŒ์ผ์— git hook๋ช…๋ น์„ ์ˆ˜ํ–‰ํ•˜๊ณ  ๋‹ค์‹œ git addํ•  ํ•„์š”์—†์ด ์ž๋™์œผ๋กœ unstaged ํŒŒ์ผ์„ staged๋กœ ์˜ฌ๋ฆฐ ํ›„ commit ํ˜น์€ push๋ฅผ ์ˆ˜ํ–‰ํ•ด์ค€๋‹ค.


lint-staged ์„ค์ •

package.json์€ ์•„๋ž˜์™€ ๊ฐ™์ด ์„ค์ •ํ–ˆ๋‹ค.

"scripts": {
  "postinstall": "husky install",
  "lint": "eslint --cache .",
  "format": "prettier --write --cache .",
  "precommit": "lint-staged",
  "prepush": "npm run lint && npm run format"
},
"lint-staged": {
  "*.{js,jsx,ts,tsx}": [
    "npm run format"
  ]
},

git hook์—๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ๋“ฑ๋กํ•˜์˜€๋‹ค.

# ์ปค๋ฐ‹ ์ „์—๋Š” prettier๋กœ ํฌ๋งทํŒ…๋งŒ ์ง„ํ–‰
# list-staged๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์ˆ˜์ •๋œ unstaged ํŒŒ์ผ๊นŒ์ง€ ์ปค๋ฐ‹
$ npx husky add .husky/pre-commit "npm run precommit"

# ํ‘ธ์‰ฌ ์ „์—๋Š” prettier & eslint ๊ฒ€์‚ฌ ์ง„ํ–‰
# ํ‘ธ์‰ฌํ•  ๋•Œ์—๋Š” stage ๊ฑฑ์ •์ด ์—†์œผ๋ฏ€๋กœ list-staged๊ฐ€ ์•„๋‹Œ ์Šคํฌ๋ฆฝํŠธ ์‚ฌ์šฉ
$ npx husky add .husky/pre-push "npm run prepush"

Ref