ํ์ผ์ ์ ์ฅํ ๋๋ง๋ค, ์ฝ๋๋ฅผ ์ฌ์ฉ์๊ฐ ์ํ๋ ํ์์ผ๋ก ๋ชจ์์ ์์๊ฒ ๋ง๋ค์ด์ฃผ๋ Node.js ํจํค์ง์ด๋ค
ํ์ผ์ ์ ์ฅํ ๋๋ง๋ค ์ผ๊ด์ฑ์๊ฒ ์ฝ๋๋ฅผ ์งค ์ ์๋๋ก ๋์์ค๋ค.
// prettier-ignore (Before)
foo(gatsbyLongArg(),soManyParameters(),gatsbyInit(),gatsbyMustUsedIt(), gatsbyPrettierConfigThis())
//(after)
foo(
gatsbyLongArg(),
soManyParameters(),
gatsbyInit(),
gatsbyMustUsedIt(),
gatsbyPrettierConfigThis()
)
Prettier๋ VSCode ํ์ฅ๊ธฐ๋ฅ์ ์ด์ฉํ์ฌ ์ค์นํด ์ค ์์๊ณ Node์ npm ๊ธฐ๋ฅ์ ํตํด ์ค์น๊ฐ ๊ฐ๋ฅํ๋ค
npm i -D prettier
Prettier ์ค์ ํ์ผ ๋ง๋ค๊ธฐ ( .prettierrc.json )
์ด์ ๋ํ์ ์ธ ์ค์ ์ ์์๋ณผํ ๋ฐ, ๊ทธ ์ธ ์ค์ ์ ์ฌ๊ธฐ์ํ์ธ : prettier.io/docs/en/options.html
singleQuote: ๋ฌธ์์ด ์
๋ ฅ์ "
๋ฅผ ์ธ์ง '
๋ฅผ ์ฌ์ฉํ ์ง ์ค์ ํ ์ ์์ด์. ์ ๋ '
๋ฅผ ์ฌ์ฉํ๊ธฐ์ true๋ก ์ค์ ํด ๋์์ต๋๋ค.
semi: ์ธ๋ฏธ์ฝ๋ก (;) ์ฌ์ฉ์ ๊ดํ ์ค์ ์ด์์. ์ ๋ ์ฌ์ฉํ๋ฏ๋ก true
๋ก ๋๊ณ ์ฌ์ฉํด์.
tabWidth: ๋ค์ฌ์ฐ๊ธฐ์ ํฌ๊ธฐ๋ฅผ ์ ํ ์ ์์ด์. ์ ๋ 2์นธ
์ผ๋ก ๋๊ณ ์จ์. 4์นธ
์ผ๋ก ๋๊ณ ์ฐ๋ฉด ๋ค์ฌ์ฐ๊ธฐ๊ฐ ์ค์ฒฉ๋ ์์ ์ฝ๋ ๋ท๋ถ๋ถ์ด ์๋ณด์ด๋ ๊ฒฝ์ฐ๊ฐ ์๊ธฐ๋๋ผ๊ตฌ์....ใ
trailingComma: ๊ฐ์ฒด ๋๋ ๋ฐฐ์ด์ด ์ฌ๋ฌ์ค๋ก ๊ตฌ์ฑ๋์ด ์์ผ๋ฉด ๋ค์๊ณผ ๊ฐ์ด ๋งจ ๋ง์ง๋ง ์ค์ ์ผํ๋ฅผ ๋ถ์ฌ์ค์ง ์ค์ ํ ์ ์์ด์.
none
์ด๋ฉด ์ผํ๋ฅผ ๋ถ์ด์ง ์๊ณ , es5
์ด๋ฉด ๊ฐ์ฒด, ๋ฐฐ์ด์ ์ฌ์ฉํ๊ฒ ๋ ๋ ์ผํ๋ฅผ ๋ถ์ด๊ณ , all
์ด๋ฉด ํจ์๋ฅผ ์ฌ์ฉ ํ ๋ ์ธ์๋ฅผ ์ ๋ฌ ํ ๋๋ ์ผํ๋ฅผ ๋ถ์
๋๋ค.
printWidth: ์ค ๋ฐ๊ฟํ ํญ์ ๊ธธ์ด๋ฅผ ์ค์ ํด์ค ์ ์์ด์.๐
{
"arrowParens": "avoid", // ํ์ดํ ํจ์ ๊ดํธ ์ฌ์ฉ ๋ฐฉ์
"bracketSpacing": false, // ๊ฐ์ฒด ๋ฆฌํฐ๋ด์์ ๊ดํธ์ ๊ณต๋ฐฑ ์ฝ์
์ฌ๋ถ
"endOfLine": "auto", // EoF ๋ฐฉ์, OS๋ณ๋ก ์ฒ๋ฆฌ ๋ฐฉ์์ด ๋ค๋ฆ
"htmlWhitespaceSensitivity": "css", // HTML ๊ณต๋ฐฑ ๊ฐ๋ ์ค์
"jsxBracketSameLine": false, // JSX์ ๋ง์ง๋ง `>`๋ฅผ ๋ค์ ์ค๋ก ๋ด๋ฆด์ง ์ฌ๋ถ
"jsxSingleQuote": false, // JSX์ singe ์ฟผํ
์ด์
์ฌ์ฉ ์ฌ๋ถ
"printWidth": 80, // ์ค ๋ฐ๊ฟ ํ ํญ ๊ธธ์ด
"proseWrap": "preserve", // markdown ํ
์คํธ์ ์ค๋ฐ๊ฟ ๋ฐฉ์ (v1.8.2)
"quoteProps": "as-needed" // ๊ฐ์ฒด ์์ฑ์ ์ฟผํ
์ด์
์ ์ฉ ๋ฐฉ์
"semi": true, // ์ธ๋ฏธ์ฝ๋ก ์ฌ์ฉ ์ฌ๋ถ
"singleQuote": true, // single ์ฟผํ
์ด์
์ฌ์ฉ ์ฌ๋ถ
"tabWidth": 2, // ํญ ๋๋น
"trailingComma": "all", // ์ฌ๋ฌ ์ค์ ์ฌ์ฉํ ๋, ํํ ์ฝค๋ง ์ฌ์ฉ ๋ฐฉ์
"useTabs": false, // ํญ ์ฌ์ฉ ์ฌ๋ถ
"vueIndentScriptAndStyle": true, // Vue ํ์ผ์ script์ style ํ๊ทธ์ ๋ค์ฌ์ฐ๊ธฐ ์ฌ๋ถ (v1.19.0)
"parser": '', // ์ฌ์ฉํ parser๋ฅผ ์ง์ , ์๋์ผ๋ก ์ง์ ๋จ
"filepath": '', // parser๋ฅผ ์ ์ถํ ์ ์๋ ํ์ผ์ ์ง์
"rangeStart": 0, // ํฌ๋งทํ
์ ๋ถ๋ถ ์ ์ฉํ ํ์ผ์ ์์ ๋ผ์ธ ์ง์
"rangeEnd": Infinity, // ํฌ๋งทํ
๋ถ๋ถ ์ ์ฉํ ํ์ผ์ ๋ ๋ผ์ธ ์ง์ ,
"requirePragma": false, // ํ์ผ ์๋จ์ ๋ฏธ๋ฆฌ ์ ์๋ ์ฃผ์์ ์์ฑํ๊ณ Pragma๋ก ํฌ๋งทํ
์ฌ์ฉ ์ฌ๋ถ ์ง์ (v1.8.0)
"insertPragma": false, // ๋ฏธ๋ฆฌ ์ ์๋ @format marker์ ์ฌ์ฉ ์ฌ๋ถ (v1.8.0)
"overrides": [
{
"files": "*.json",
"options": {
"printWidth": 200
}
}
], // ํน์ ํ์ผ๋ณ๋ก ์ต์
์ ๋ค๋ฅด๊ฒ ์ง์ ํจ, ESLint ๋ฐฉ์ ์ฌ์ฉ
}
ESLint๋ ES ์ Lint๋ฅผ ํฉ์ฑ์ด์ ๋๋ค. ES๋ Ecma Script, Lint๋ ์๋ฌ๊ฐ ์๋ ์ฝ๋์ ํ์๋ฅผ ๋ฌ์๋๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค.
๋ฐ๋ผ์, ESLint๋ ์๋ฐ์คํฌ๋ฆฝํธ ๋ฌธ๋ฒ์์ ์๋ฌ๋ฅผ ํ์ํด์ฃผ๋ ๋๊ตฌ์ ๋๋ค.
Lint๋
์ํค๋ฐฑ๊ณผ์๋ lint์ ๋ํ ์ ์๊ฐ ์์ด ๊ฐ์ ธ์๋ค.
Lint๊ฐ ๊ผญ ์๋ฐ์คํฌ๋ฆฝํธ ์ธ์ด์๋ง ์ ์ฉ๋๋ ๋ง์ด ์๋๋ผ๋ ๊ฒ์ ์๊ฒ ๋์๋ค.
๋ฆฐํธ(lint) ๋๋ ๋ฆฐํฐ(linter)๋ ์์ค ์ฝ๋๋ฅผ ๋ถ์ํ์ฌ ํ๋ก๊ทธ๋จ ์ค๋ฅ, ๋ฒ๊ทธ, ์คํ์ผ ์ค๋ฅ, ์์ฌ์ค๋ฌ์ด ๊ตฌ์กฐ์ฒด์ ํ์(flag)๋ฅผ ๋ฌ์๋๊ธฐ ์ํ ๋๊ตฌ๋ค์ ๊ฐ๋ฆฌํจ๋ค. ์ด ์ฉ์ด๋ C ์ธ์ด ์์ค ์ฝ๋๋ฅผ ๊ฒ์ฌํ๋ ์ ๋์ค ์ ํธ๋ฆฌํฐ์์ ๊ธฐ์ํ๋ค.
(*์ถ์ฒ: ์ํค๋ฐฑ๊ณผ)
๋ง์ ์ฌ๋๋ค๊ณผ ํ์ ํ ๋ ํนํ ์ ์ฉํฉ๋๋ค. ์๋ฌ์ ์ฝ๋ฉ ์คํ์ผ์ ์ก์์ฃผ๊ธฐ ๋๋ฌธ์ ํ ์ฌ๋์ด ์ฝ๋ฉํ ๊ฒ์ฒ๋ผ ๋ฉ๋๋ค!
$ npm install -D eslint
// or
$ yarn add -D eslint
๊ทผ๋ฐ eslint ์ค์น๋ง ํ๋ค๊ณ ๋ฐ๋ก ์ฌ์ฉํ ์ ์๋๊ฒ์๋๋ผ extension๋ ๊ฐ์ด ์ค์นํด์ฃผ์ด์ผํฉ๋๋ค.
ESLint์ ์ธ๋ถ ์ค์ ์ package.json
์ eslintConfig
์์ ํด๋ ๋๊ณ .eslintrc.js
, .eslintrc.json
, .eslintrc.yaml
, .eslintrc.yml
ํ์ผ ์ค ํ๋๋ฅผ ์ ํํด์ ํ ์ ์๋ค.
์ฐ๋ฆฌ๋ root ๋๋ ํ ๋ฆฌ์ .eslintrc.jsํ์ผ์ ์์ฑํ์.
2๏ธโฃ ESLint ์ธํ
ํ๋ก์ ํธ root์ .eslintrc.json ๋ผ๋ ์ด๋ฆ์ ํ์ผ์ ์ถ๊ฐํ๊ณ ์๋ ๋ด์ฉ์ ์ถ๊ฐํ๋ค.
{
"extends": "react-app"
}
2๏ธโฃ Prettier ์ค์น
Prettier์ ESLint๋ฅผ ์ฐ๊ฒฐ
npm i prettier eslint-config-prettier eslint-plugin-prettier -D
๊ทธ๋ฆฌ๊ณ .eslintrc.json์ ์ฝ๋๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ์ ๋ฐ์ดํธ
{
"extends": ["react-app", "plugin:prettier/recommended"]
}
1. default config ์ง์ฐ๊ธฐ(package.json)
๋ ์ข์ ์ธํ
์ ํ๊ธฐ์ํด ์๋ ๋ถ๋ถ์ ์ง์ด๋ค.
CRA๋ก ํ๋ก์ ํธ๋ฅผ ์์ฑํ๋ฉด package.json์์ ๊ธฐ๋ณธ์ ์ผ๋ก ์ธํ
๋์ด์์
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
2. install eslint
npm install eslint --save-dev
3. setup eslint
npx eslint --init
์ดํ ์ค์ ๊ณผ์ ์์๋ ๋ค์๊ณผ ๊ฐ์ด ์
๋ ฅ
4. ํ์ธํ๊ธฐ
์์ ๊ฐ์ ์ ์ฐจ๋ฅผ ๋ฐ๋ผ์ฃผ๋ฉด ํ์ํ package๋ค์ด ์ค์น๋๋ค.
์ค์ ๊ณผ์ ์ด ๋๋๋ฉด .eslintrc.json ํ์ผ์ด ์์ฑ๋๊ณ ์๋์ ๊ฐ์ ๋ด์ฉ์ด ์ฑ์์ง๊ฒ ๋ฉ๋๋ค.
5. ํ๋ฆฌํฐ์ด ํจ๊ป ์ฌ์ฉ (ํ๋กํฐ์ด ์ค์น์๋ฃ ํ)
Prettier์ ESLint๋ฅผ ๊ฐ์ด ์ฌ์ฉํ๋ ค๋ฉด ์๋์ ๋ช
๋ น์ด๋ฅผ ์ฌ์ฉํด์ผ ํ๋ค.
npm install eslint-plugin-prettier eslint-config-prettier --save-dev
๊ทธ๋ฆฌ๊ณ ์๋์ ๋ด์ฉ์ .eslintrc ํ์ผ์ ์ถ๊ฐํ๋ค.
{
"plugins": ["prettier"],
"extends": ["eslint:recommended", "plugin:prettier/recommended"],
"rules": {
"prettier/prettier": "error"
}
}
plugins
์ฐ์ plugin ์ข
๋ฅ๋ ์ฌ๋ฌ ๊ฐ์ง ์๋๋ฐ, ์๋ฅผ ๋ค์ด
eslint-config-airbnb-base: ์์ด๋น์๋น ๋ฆฐํธ ํ๋ฌ๊ทธ์ธ
eslint-config-next: Next.js ์ ์ฉ ๋ฆฐํธ ํ๋ฌ๊ทธ์ธ
eslint-plugin-react: ๋ฆฌ์กํธ ์ ์ฉ ํ๋ฌ๊ทธ์ธ
eslint-plugin-react-hooks: React Hooks์ ๊ท์น์ ๊ฐ์ ํด์ฃผ๋ ํ๋ฌ๊ทธ์ธ
eslint-plugin-import: ES2015+์ import/export ๊ตฌ๋ฌธ์ ์ง์
eslint-plugin-jsx-a11y: JSX ๋ด์ ์ ๊ทผ์ฑ ๋ฌธ์ ์ ๋ํด ์ฆ๊ฐ์ ์ธ AST๋ฆฐํ
ํผ๋๋ฐฑ์ ์ ๊ณต
eslint-plugin-prettier: ๋ฆฐํธ ์์ ์ฌ์ฉํ ํ๋ฆฌํฐ์ด ํ๋ฌ๊ทธ์ธ
eslint-config-prettier: ์๊ฑด ๋ฆฐํธ ์ค์ ๊ณผ ์ค๋ณต๋๋ ๋ถ๋ถ์ด ์์ผ๋ฉด ํ๋ฆฌํฐ์ด ๋ฃฐ์์ ์ ์ธํ๋ ํ๋ฌ๊ทธ์ธ
@typescript-eslint/eslint-plugin: : ํ์
์คํฌ๋ฆฝํธ ์ ์ฉ ๋ฆฐํธ
๋์ถฉ ์ด๋ฌํ ํ๋ฌ๊ทธ์ธ๋ค์ด ์๋ค. ์ด๊ฒ๋ค ๋ง๊ณ ๋ ์ข ๋ฅ๋ ํจ์ฌ ๋ง๋ค.
ํ๋ก์ ํธ์ ํ์๋ก ํ ๊ฐ ํ๋ฌ๊ทธ์ธ์ npm์ด๋ yarn์ ํตํด์ ์ค์นํ๋ฉด ๋๋ค.
๋ง์ฝ ์์ @typescript-eslint/eslint-plugin์ ์ธ ๊ฑฐ๋ฉด, eslintrc ํ์ผ์ plugins ๋ฐฐ์ด์ ํด๋น ๋ชจ๋์์ ์ ๊ณตํ๋ @typescript-eslint๋ฅผ ์ฅ์ฐฉ์ํค๋ฉด ๋๊ณ , ๋ค๋ฅธ ๋ชจ๋๋ ๊ฐ์ด ์ธ ๊ฑฐ๋ฉด ๋ฐฐ์ด์ ๊ฐ์ด ์ถ๊ฐํ๋ฉด ๋๋ค.
๊ทธ๋ฆฌ๊ณ ์ด๋ฌํ ํ๋ฌ๊ทธ์ธ๋ค์ ์ฝ๊ฒ ์ ๋ฆฌ๋ airbnb๊ฐ ์กด์ฌํ๋๋ฐ, ๋ถ๋์ด ๋๋ฌด ๋ง์์ ์๋ก์ด 2ํ์ผ๋ก ๋ง๋ค์ด์ผ๊ฒ ๋ค..