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.
- ์ผ๊ด์ฑ ์๊ณ ์๋ฌ๋ฅผ ํผํ ์ ์๋ ์ฝ๋๋ฅผ ์์ฑํ๊ธฐ ์ํด์ ๋ง๋ค์ด์ง ์ฝ๋ ๋ถ์ ํด
- ์์ฑ๋ ์ฝ๋๋ฅผ ๋ถ์ํ์ฌ ๋ถํ์, ๋ณด์ ์๋ฐฐ, ๋ฒ๊ทธ ์ฌ์ง๊ฐ ์๋ ์ฝ๋๋ฅผ ์๋ฆผ
- ์ปค์คํฐ๋ง์ด์ง์ ํ์ฉํ๊ธฐ ๋๋ฌธ์ ํ์ํ ๊ท์น์ ์ค์ ๊ฐ๋ฅ
- ์ฝ๋ ํฌ๋งทํฐ๋ก ์คํ์ผ์ ๋ํ ์๊ฐ ๋ฐ ์๋์ง ์ ์ฝ
- ์คํ์ผ์ ๋ํ ํ ๋ก ์ด ์ค๊ณ , ์ค์ํ ๊ฐ๋ฐ์ ์ง์ค์ด ๊ฐ๋ฅ
- ๋ง์ ์ธ์ด๋ค์ ์ง์ํ๊ณ ์์ (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
- Prettier์ ์ถฉ๋ํ๋ ESLint ๊ท์น(ํฌ๋งทํ )์ ๋นํ์ฑํํ๋ ๋ฐ ๋์์ด ๋๋ ESLint ๊ตฌ์ฑ
- ESLint๋ ์ฝ๋ ์คํ์ผ ๊ท์น์ ์ ์ฉํ๋ฉฐ, Prettier๋ ์ฝ๋ ์คํ์ผ์ ์๋์ผ๋ก ์ง์
- ESLint์ ํฌ๋งทํ
์ ๊ด๋ จํ ๊ท์น์ด ํฌํจ๋์ด ์์ด Prettier์ ์ผ๋ถ ์ถฉ๋ํ๋ฏ๋ก
eslint-config-prettier
๋ฅผ ์ฌ์ฉํ์ฌ ํธํ๋๋๋ก ์กฐ์
- ์ค์น ์๋ฃ ํ ํ์ ๊ฐ ๊ท์น ์ค์ ํ์
- ์๋ ๋ช
๋ น์ด์ ์ฌ์ฉํ๋ฉด ๋ฌธ๋ต ํ์์ ํตํด์ ๊ฐํธํ
.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.ํ์ฅ์
ํ์ผ์ ๋ฃจํธ ๋๋ ํ ๋ฆฌ์ ์ ์ฅ.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 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 ๊ฒ์ฌ ์คํ
$ 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
commit์ ์งํํ ์ฝ๋๋ formatting, push๋ฅผ ์งํํ ์ฝ๋๋ lint๋ฅผ ์๋์ผ๋ก ์ ์ฉํด๋ณด์.
- Husky docs
- Git Hook ์ค์ ์ ์ฝ๊ฒ ์ค์ ํด์ฃผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
- ํ์ ๊ฐ๊ฐ์ธ์ด
npm install
๋ง ์ํํ๋๋ผ๋ ์ฌ์ ์ ์ค์ ํ Git Hook์ ์ ์ฉ์ํฌ ์ ์๋ค.
- Git์์ ํน์ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๊ธฐ ์ด์ ๊ณผ ์ดํ์ Hook ๋์์ ์คํํ ์ ์๊ฒํ๋ ๊ฒ
- Git Hook ์ค์ ์ ๊น๋ค๋ก์ฐ๋ฉฐ, ํ์๋ค์ด repo๋ฅผ ๋ค์ด๋ก๋ ๋ฐ๊ณ ๋งค๋ด์ผํ๊ฒ ์ฌ์ ๊ณผ์ ์ ์ํํด์ผ hook ์คํ์ด ๋ณด์ฅ
- Husky๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํตํด Git Hook์ ๊ฐ๋จํ๊ฒ ์ค์ ํ ์ ์๋ค.
# ์ค์น
$ 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
๋ก ์ค์ ํ๋ค.
# ๋ช
๋ น์ด
$ 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"
Husky๋ฅผ ์ฌ์ฉํ์ฌ commit์ ์งํํ๊ณ git status
๋ก ํ์ธํด๋ณด๋ฉด modified๋ ํ์ผ(unstaged)์ด ์ฌ์ ํ ๋จ์์๋ค. git commit
๋ช
๋ น์ด๋ฅผ ์
๋ ฅํ ํ ์ด๋ค ํ๋ฆ์ด ์์์๊น
- ์ปค๋ฐ ์ ๋ณ๊ฒฝ๋ ํ์ผ ์กด์ฌ - staged
- ์ปค๋ฐ ๋ช
๋ น์ด ์คํ -
git commit -m "์ปค๋ฐ๋ฉ์์ง"
- git hook pre-commit ๋์ -
npm run format
- prettier๋ก ํฌ๋งทํ ๋ ํ์ผ ์กด์ฌ - unstaged
- ์ปค๋ฐ ์๋ฃ
ํฌ๋งทํ
๋ ํ์ผ์ ๋ค์ ์ปค๋ฐํด์ผ๋๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ฏ๋ก 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๋ฅผ ์ํํด์ค๋ค.
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"
- eslint docs
- prettier docs
- Husky docs
- lint-staged docs
- gabia library
- wanted preonboarding internship