1. Why?
과제 테스트를 React와 TypeScript로 진행하는 중이다. 간만에 Eslint와 Prettier를 설정하다보니 기억도 가물가물한데, 그 김에 Eslint와 Prettier를 어떻게 설정했는지를 설명하고 왜 이렇게 설정했는지에 대해서 적어보고자 한다.
아래의 설정은 React + TypeScript + pnpm 기준이다.
2. Eslint init
잠깐!
일단 설명하기 전에, 나는 실수로 eslint를 정상적으로 적용시키지않고 과제를 제출했다...
eslint를 설치하고 나서 .eslintrc.json 파일도 정상적으로 설정해줬으니 알아서 잘 돌아가겠거니~ 했는데
과제 제출 후 글을 작성하는 도중에 혹시나 하고 var를 코드에 입력해봤는데 에러가 출력되지 않았다...
뒤늦게 eslint init을 통해서 다시 eslint를 설정하고 .eslintrc.json파일과 프로젝트 코드를 수정했다.
물론 소 잃고 외양간 고친거긴 하지만,,, 다음부터 eslint 실수하는 일은 없겠지....😢
결론
여러분들은 이런 일 없게 그냥 처음부터 eslint init으로 설정하세요. 그러니까 eslint init 방법부터 설명하겠습니다.
설명
pnpm 기준으로 pnpm eslint --init 명령어를 입력하면 어떻게 eslint를 사용할지에 대해 물어보는 첫 선택지가 출력된다.
- 문법 오류를 체크한다.
- 문법 오류를 체크하고 문제점을 찾는다.
- 문법 오류, 문제점을 찾고 지정한 코드 스타일을 강제한다.
eslint는 보편적인 선택지를 default값으로 주기에, 정 모르겠으면 그냥 default로 가는것도 괜찮다.
난 코드 스타일은 prettier로 관리할꺼니까 2번을 선택했다.
프로젝트에서 어떤 모듈 형식을 쓰니?
- JavaScript module (import/export)
- CommonJs (require/exports)
- 둘 다 아님
node Js에서는 CommonJs를 default로 쓴다고 알고 있다. 하지만 React나 Vue에서는 Es module을 기본으로 쓰니까 1번 선택하면 된다.
어떤 프레임워크 쓰니?
타입스크립트 쓰니?
뜬금없는데 타입스크립트 정말 좋다. 처음 사용할때는 좀 불편했는데 적응하고나니까 Js보다 100배는 편하다...
혹시 아직 안 써본 사람이라면 꼭 사용하길
코드 실행 환경에 대해서 물어본다. 하나만 선택할 수도, 둘 다 선택할 수도 있다.
- 브라우저
- Node
Next.js같은 풀스택 프레임워크라면 둘 다, Node.js로 백엔드를 만들거라면 Node를, React나 Vue로 웹 프론트엔드를 만들거라면 Browser를 선택하면 된다.
설정 파일은 뭘로 할래?
- JavaScript
- YAML
- JSON
보통은 JS나 JSON으로 선택하는데, 난 익숙한 JSON으로 했다.
지금까지 선택한대로 설정하려면 위의 패키지들이 필요한데 설치해줘?
Yes
어떤 패키지 매니저를 사용하니?
- npm
- yarn
- pnpm
https://cksxkr5193.tistory.com/2
이 때 패키지매니저를 결정한 이후로 계속 pnpm을 사용하고 있다.
나는 위와 같이 선택했고, 결과는 다음과 같다.
{
"env": {
"browser": true,
"es2021": true
},
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:react/recommended"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module"
},
"plugins": [
"@typescript-eslint",
"react"
],
"rules": {
}
}
3. Eslint 결과물
하지만 eslint init만 해줬다고 끝이아니다. 추가적인 설정도 해줘야 한다. 사전과제에서는 다음과 같이 설정했다.
extends
"extends": [
"airbnb",
"airbnb-typescript",
"airbnb/hooks",
"plugin:prettier/recommended",
"prettier"
]
다른 eslint 설정을 상속받은 것. 가장 대중적이고 유명한 airbnb룰을 선택했다.
settings
"settings": {
"import/resolver": {
"alias": {
"map": [["@", "./src"]],
"extensions": [".ts", ".tsx", ".js", ".jsx", ".json"]
}
}
},
절대경로 설정 시 에러가 출력되지 않도록 import/resolver에 "@"로 시작되는 경로를 인식할 수 있게 했다.
rules
"rules": {
"linebreak-style": 0,
"prettier/prettier": [
"error",
{
"endOfLine": "auto"
}
],
"import/prefer-default-export": "off",
"react/react-in-jsx-scope": "off",
"import/no-extraneous-dependencies": [
"error",
{
"devDependencies": true,
"optionalDependencies": true,
"peerDependencies": true
}
],
"react/require-default-props": "off",
"import/extensions": [
"error",
"ignorePackages",
{
"js": "never",
"jsx": "never",
"ts": "never",
"tsx": "never",
"json": "never"
}
],
"import/order": [
"error",
{
"groups": ["builtin", "external", "parent", "sibling", "index"],
"pathGroups": [
{
"pattern": "react",
"group": "external",
"position": "before"
},
{
"pattern": "react-router-dom",
"group": "external",
"position": "before"
},
{
"pattern": "@/**/*",
"group": "parent",
"position": "before"
}
],
"pathGroupsExcludedImportTypes": ["builtin"],
"newlines-between": "always",
"alphabetize": {
"order": "asc",
"caseInsensitive": true
}
}
]
}
}
- "linebreak-style": 0,
- "prettier/prettier"
eslint의 줄 바꿈 스타일에 대한 규칙을 비활성화하고, prettier에서 처리하도록 했다.
이런 스타일은 모두 prettier에서 처리하는쪽이 낫다고 생각한다.
- "import/prefer-default-export": "off"
하나만 export할거면 default export로 처리하는 규칙인데, 처음 type 파일 생성해서 export할때는 default 달아주고 그 다음 추가할때는 삭제해주는게 불편해서 off.
- "react/react-in-jsx-scope": "off"
최상단에 무조건 import react를 기입해야하는 규칙인데 React 17버전 이후로는 없어도 된다. 마찬가지로 불편해서 off
- "react/require-default-props": "off"
optional한 props는 기본값을 가져야하는 규칙이다. 아직 크게 필요성을 느낀적 없어서 off했다.
- "import/no-extraneous-dependencies":
@vitejs/plugin-react패키지를 사용하기 위해 devDependencies, optionalDependencies, peerDependencies 등을 참조해서 사용할 수 있게 했다.
- "import/extensions"
import 시 파일의 확장자를 모두 명시해야하는 rule이다. js, jsx, ts, tsx, json의 경우에는 굳이 명시하지 않는게 더 깔끔해보여서 ignorePackages로 설정했다.
- "import/order"
import 순서를 정렬하는 rule이다. 원래는 Eslint에서 import order를 하기보단 formatter인 Prettier에서 설정하는게 원래의 역할에 더 가깝다고 생각해 Prettier에서 처리하도록 설정했다.
하지만 trivago의 import sort가 생각보다 불편한 점이 많았고 eslint와 충돌이 일어나는 부분도 있어 그냥 eslint로 설정했다.
{
"env": {
"browser": true,
"es2021": true
},
"extends": [
"airbnb",
"airbnb-typescript",
"airbnb/hooks",
"plugin:prettier/recommended",
"prettier",
],
"overrides": [
{
"env": {
"node": true
},
"files": [".eslintrc.{js,cjs}"],
"parserOptions": {
"sourceType": "script"
}
}
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": "**/tsconfig.json",
"ecmaVersion": "latest",
"sourceType": "module"
},
"plugins": ["@typescript-eslint", "prettier", "import"],
"ignorePatterns": ["node_modules/"],
"settings": {
"import/resolver": {
"alias": {
"map": [["@", "./src"]],
"extensions": [".ts", ".tsx", ".js", ".jsx", ".json"]
}
}
},
"rules": {
"linebreak-style": 0,
"prettier/prettier": [
"error",
{
"endOfLine": "auto"
}
],
"import/prefer-default-export": "off",
"react/react-in-jsx-scope": "off",
"import/no-extraneous-dependencies": [
"error",
{
"devDependencies": true,
"optionalDependencies": true,
"peerDependencies": true
}
],
"react/require-default-props": "off",
"import/extensions": [
"error",
"ignorePackages",
{
"js": "never",
"jsx": "never",
"ts": "never",
"tsx": "never",
"json": "never"
}
],
"import/order": [
"error",
{
"groups": ["builtin", "external", "parent", "sibling", "index"],
"pathGroups": [
{
"pattern": "react",
"group": "external",
"position": "before"
},
{
"pattern": "react-router-dom",
"group": "external",
"position": "before"
},
{
"pattern": "@/**/*",
"group": "parent",
"position": "before"
}
],
"pathGroupsExcludedImportTypes": ["builtin"],
"newlines-between": "always",
"alphabetize": {
"order": "asc",
"caseInsensitive": true
}
}
]
}
}
결과적으로 위와 같은 설정이 완료되었다.
+ 추가
eslint-plugin-tailwindcss도 설치해주었다. Tailwind CSS 쓰는 사람에게 강력하게 추천하는 패키지다.
나름대로 혼자 신경써서 '크기가 맨 앞에, flex는 그 다음, 사용자 지정 스타일은 그 다음...' 하는 식으로 정렬해주고 있었는데 한 방에 고민을 해결해줬다.
4. Prettier
{
"arrowParens": "always",
"htmlWhitespaceSensitivity": "css",
"bracketSameLine": false,
"bracketSpacing": true,
"printWidth": 80,
"proseWrap": "preserve",
"quoteProps": "as-needed",
"semi": true,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "es5",
"useTabs": false
}
사실 대부분의 설정은 default 값과 비슷하다. singleQuote 정도만 다른데, 그냥 이건 개인 선호라 특별한 이유는 없다. 다만 광활한 대지를 달려나가는 코드들을 보면서 광개토대왕의 위엄을 느낄게 아니라면 tabWidth는 무조건 2를 쓰는게 좋다.
+ 추가
여기도 마찬가지로 자동 정렬을 위해 prettier-plugin-tailwindcss 패키지를 설치해주었다.
자세한 내용은 https://tailwindcss.com/blog/automatic-class-sorting-with-prettier 여기를 참조하면 된다.
4. 래퍼런스
https://tech.kakao.com/2019/12/05/make-better-use-of-eslint/
https://xionwcfm.tistory.com/359
https://www.daleseo.com/eslint-config/
https://www.daleseo.com/js-prettier-config/
https://univdev.page/posts/eslint-prettier-installation/
https://tailwindcss.com/blog/automatic-class-sorting-with-prettier
'Frontend > Etc' 카테고리의 다른 글
액션, 계산 분리해보기(함수형 프로그래밍) (0) | 2024.01.08 |
---|---|
Vite를 사용하면서 svg 컴포넌트로 만들기 (0) | 2024.01.01 |
npm VS yarn Vs pnpm Vs yarn berry 뭘 써야 해??? (0) | 2023.07.07 |