1. ESLint
์ค๋๋ ์ค์จํฐ์ ๋ณดํธ๋ผ๊ธฐ๊ฐ์ ๊ฒ์ ์์ด๋ก ๋ฆฐํธ(Lint)๋ผ๊ณ ๋ถ๋ฆ
๋๋ค.
๋ณดํธ๋ผ๊ธฐ๊ฐ ๋ง์ผ๋ฉด ์ท์ด ๋ณด๊ธฐ์ ์์์ง ์์๋ฐ ์ฝ๋์๋ ์ด๋ฐ ๋ณดํ๋ผ๊ธฐ์ฒ๋ผ ๋ค์ฌ์ฐ๊ธฐ๋ฅผ ๋ง์ถ์ง ์์ ๊ฒฝ์ฐ,
์ ์ธํ ๋ณ์๋ฅผ ์ฌ์ฉํ์ง ์์ ๊ฒฝ์ฐ ๋ฑ ๋ณด๊ธฐ์ ์์์ง ์์ ์ฝ๋๋ฅผ ์๋ฏธํฉ๋๋ค.
๋ณดํธ๋ผ๊ธฐ๊ฐ ์๋ ์ท์ ์
์ ์๋ ์๋ฏ์ด ์ด๋ฐ ์ฝ๋๋ก ๋ง๋ ์ดํ๋ฆฌ์ผ์ด์
๋ ๋์์ ํฉ๋๋ค.
๊ทธ๋ฌ๋ ์ฝ๋์ ๊ฐ๋
์ฑ์ด ๋จ์ด์ง๊ณ ์ ์ ์ ์ง๋ณด์ํ๊ธฐ๊ฐ ํ๋ค์ด ์ง๋๋ค.
๋ณดํธ๋ผ๊ธฐ๋ฅผ ์ ๊ฑฐํ๋ Lint roller์ฒ๋ผ
์ฝ๋์ ์ค๋ฅ๋ ๋ฒ๊ทธ, ์คํ์ผ ๋ฐ์๋ฅผ ์ ๊ฒํ๋ ๊ฒ์ ๋ฆฐํธ(Lint) ํน์ ๋ฆฐํฐ(Linter)๋ผ๊ณ ๋ถ๋ฆ
๋๋ค.
- https://eslint.org/docs/latest/rules/
- ๊ฐ๋ฐ์๋ค์ด ํน์ ํ ๊ท์น์ ๊ฐ์ง๊ณ ์ฝ๋๋ฅผ ์งค์์๊ฒ ๋์์ฃผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
- ์ฃผ์ ๊ธฐ๋ฅ
- ์๋ฐ์คํฌ๋ฆฝํธ๋ฅผ ์ฐ๋ ๊ฐ์ด๋ ๋ผ์ธ ์ ์ ๋ฑ ํฌ๋งทํฐ(formatter) ์ญํ ๋ ํ์ง๋ง
- ์ฃผ์ ๊ธฐ๋ฅ์ ๋ฌธ๋ฒ ์ค๋ฅ ์ก๋ ๊ฒ
1$ npm i eslint # eslint ์ค์น2$ touch .eslintrc.js # .eslintrc.js ์์ฑ3$ npm run lint # ๋ฆฐํธ ์คํ
๊ท์น์ ์ฐพ์์ .eslintrc.js์ ์ ์ฉํฉ๋๋ค.
1// .eslintrc.js2module.exports = {3extends: ['eslint:recommended'],4}
2. Prettier
- ์ฝ๋ ํ์์ ๋ง์ถ๋๋ฐ ์ฌ ์ฉ ์์๋ฐ์ดํ(โ)๋ฅผ ์ฌ์ฉํ ์ง ํฐ ๋ฐ ์ดํ(โ)๋ฅผ ์ฌ์ฉํ ์ง,
- Indent ๊ฐ์ 2๋ก ์ค์ง 4๋ก ์ค์ง๋ฑ๋ฑ, ์๋ฌ ์ฐพ๋๊ฒ์ด ์๋ ์ฝ๋ ํฌ๋งทํฐ ์ญํ
1$ npm i prettier # prettier ์ค์น2$ npx prettier src/**/* --write # prettier ์คํ
์๋๋ฉด VSCode ํ์ฅ ๊ธฐ๋ฅ ์ฌ์ฉ
- ํ์ฅ ๊ธฐ๋ฅ์ ํผ์ ์ฌ์ฉํ ๋ ์ข์
- npm์ผ๋ก ์ค์น๋ ์ฌ๋ฌ ๊ฐ๋ฐ์์ ๊ฐ์ ํฌ๋งท์ ์ ์งํ ๋ ์ฌ์ฉ
2.1 ์ต์
3. ESLint + Prettier ํตํฉ
Prettier๋ Eslint์ ํตํฉํ๋ ๋ฐฉ๋ฒ์ ์ ๊ณตํฉ๋๋ค. ์๋ก ์ถฉ๋ํ๋ ์ต์ ์ด ์์ผ๋ฉด ํ๋ฆฌํฐ์ด ๊ท์น์ ์ฌ์ฉํ๋๊ณ ํ๋ ๋๊ตฌ์ ๋๋ค.
1$ npm i eslint-config-prettier eslint-plugin-prettier
์ค์ ํ์ผ์ eslint์ ์ถ๊ฐ
1// .eslintrc.js2module.exports = {3extends: ['eslint:recommended'],4}
4. ๋ช ๋ น์ด ์๋ํ
- Git Hook์ผ๋ก ์๋ํ
- ์๋ํฐ ํ์ฅ ๊ธฐ๋ฅ์ผ๋ก ์๋ํ
4.1 ์๋ํฐ ํ์ฅ ๊ธฐ๋ฅ์ผ๋ก ์๋ํโญ
- VSCode ์๋ํฐ์ ํ์ง๊ธฐ๋ฅ(Estention)์ Eslint, Prettier ํ์ฅ ๊ธฐ๋ฅ ์ค์น
setting.json์ค์ ํ์ผ๋ก ๊ฐ์ eslint๋ฅผ ํ์ฑํ
1// VSCode setting.json2{3"eslint.enable": true, // eslint ํ์ฑํ4"editor.codeActionsOnSave": {5// ์ ์ฅํ ๋๋ง๋ค eslint ์ฝ๋ ๊ณ ์น๊ธฐ6"source.fixAll.eslint": true7}8}
5. ์ค์ ํ์ผ ์ฐ๋ ์ต์ ์ ๋ฆฌ
5.1 VSCode setting.json์ค์
1{2/* ESLint, Prettier ์ธ์ด๋ณ ์ค์ */3"eslint.enable": true,4"editor.codeActionsOnSave": {5"source.fixAll.eslint": true6},7"prettier.singleQuote": true,8"editor.formatOnSave": false,9"editor.defaultFormatter": "esbenp.prettier-vscode",10"[html]": {11"editor.formatOnSave": true,12"editor.defaultFormatter": "vscode.html-language-features"13},14"[javascript]": {15"editor.formatOnSave": true16},17// jsx18"[javascriptreact]": {19"editor.formatOnSave": true20},21"[typescript]": {22"editor.formatOnSave": true23}24// ์ ์ธ์ด๋ค ์ธ์๋ ์ ์ฅ ์ ESLint, Prettier ์ ์ฉํ ์ธ์ด๋ฅผ ์ค์ ํ๋ฉด ๋๋ค.25}
5.2 .prettierrc.json
1{2"singleQuote": true,3"bracketSpacing": true,4"bracketSameLine": true,5"arrowParens": "avoid",6"printWidth": 1207}
5.3 .eslintrc.json
1{2"parserOptions": {3"ecmaVersion": "latest"4},5"env": {6"browser": true,7"node": true,8"commonjs": true,9"es2022": true10},11"globals": { "_": true },12"plugins": ["import", "html"],13"extends": "airbnb-base",14"rules": {15// "off" or 0 - turn the rule off16// "warn" or 1 - turn the rule on as a warning (doesnโt affect exit code)17// "error" or 2 - turn the rule on as an error (exit code is 1 when triggered)18// "no-var": "off",19"no-console": "warn",20"no-plusplus": "off",21"no-shadow": "off",22"vars-on-top": "off",23"no-underscore-dangle": "off", // var _foo;24"comma-dangle": "off",25"func-names": "off", // setTimeout(function () {}, 0);26"prefer-template": "off",27"no-nested-ternary": "off",28"max-classes-per-file": "off",29"consistent-return": "off",30"no-restricted-syntax": ["off", "ForOfStatement"], // disallow specified syntax(ex. WithStatement)31"prefer-arrow-callback": "error", // Require using arrow functions for callbacks32"require-await": "error",33"arrow-parens": ["error", "as-needed"], // a => {}34"no-param-reassign": ["error", { "props": false }],35"no-unused-expressions": [36"error",37{38"allowTernary": true, // a || b39"allowShortCircuit": true, // a ? b : 040"allowTaggedTemplates": true41}42],43"import/no-extraneous-dependencies": ["error", { "devDependencies": true }],44"max-len": [45"error",46{47"code": 120,48"ignoreComments": true,49"ignoreStrings": true,50"ignoreTemplateLiterals": true51}52] // prettier์ printWidth ์ต์ ๋์ ์ฌ์ฉ53}54}