home

ESLint 언제까지 생각 없이 쓸거냐고!

글 분류
main
키워드
eslint
생성일
2022/06/11 12:02
최근 수정일
2023/06/04 06:59
작성중

⚽️ 목표

새로운 프로젝트 시작할때 마다.. 생각없이 블로그 보면 복붙 반복하기 싫어서 작성한 게시글 → 왜? 를 대답하기 위한 게시글
부제 → Eslint + Prettier + Husky 전부다 생각하고 쓰기
수시로 업데이트 되는 게시글 입니다!

1. aribnb-config-eslint

설치

eslint을 적용 하고자 하는 프로젝트에 airbnb eslint config 집핪을 설치 → 다 직접해도 OK!, 저는 절대 귀찮지 않습니다
# ESLint airbnb 관련 플러그인 전부 설치 npx install-peerdeps --dev eslint-config-airbnb # pnpm의 경우 .npmrc에 auto-install-peers=true 추가 후 pnpm add -D eslint-config-airbnb
Bash
복사
설치된 관련 플러그인들
"devDependencies": { // ...생략 "eslint": "^8.17.0", // 설치됨 "eslint-config-airbnb": "^19.0.4", // 설치됨 "eslint-plugin-import": "^2.26.0", // 설치됨 "eslint-plugin-jsx-a11y": "^6.5.1", // 설치됨 "eslint-plugin-react": "^7.30.0", // 설치됨 "eslint-plugin-react-hooks": "^4.5.0", // 설치됨 // ...생략 }
JSON
복사

react/jsx-runtime

React 17 부터는 JSX(TSX)파일 상단에 리액트 라이브러리를 import하지 않아도됨 → plugin 추가하여 간단하게 해결가능 or rule 추가하거나

2. typescript-eslint, prettier eslint

설치

# TS관련 설정 + TS 파일 파싱을 위해 pnpm add -D @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-import-resolver-typescript
Bash
복사
eslint 기본 파서인 Espree 파서는 TS코드 해석 불가 →TS 기반 코드들을 JS 기반 코드들로 해석하려함, 물.론. 에러 천국
파서 설정 하지 않을 경우 → lint는 돌지만 에러 천국 + VS Code에선 아예 에러 창 자체를 띄우지 않음
TS 코드를 파싱 할 수 있는 파서를 따로 지정해주기 위함
TSLint는 웨안써?

recommended

대부분의 bad practice - bug를 미리 잡아주는 정도의 룰의 집합
{ "extends": [ "plugin:@typescript-eslint/eslint-recommended" ] }
JSON
복사

recommended-requiring-type-checking

typescript-eslint 파서는 TS 컴파일러 API를 이용하여 파일을 파싱 함 → 린트 하고자하는 파일의 모든 타입정보에 개입 가능
타입 관련 에러를 좀더 자세하게 추론하여 뿜뿜! → 이러케 죠은데 웨안써?
{ "extends": [ "plugin:@typescript-eslint/recommended", "plugin:@typescript-eslint/recommended-requiring-type-checking" ] }
JSON
복사

.eslintrc에 eslint-import-resolver-typescript 추가

"settings": { "import/resolver": { "node": { "extensions": [".js", ".jsx", ".ts", ".tsx"], "moduleDirectory": ["node_modules", "@types"] }, "typescript": {}, } }
TypeScript
복사
eslint가TypeScript Path를 이해하기 위해 추가하는 플러그인

3. eslint-plugin-prettier / eslint-config-prettier

설치

eslint-config-prettier → prettier와 충돌나는 eslint 설정들 비!활!성!화!
eslint-plugin-prettier → 위의 설정을 간단하게 만들어주는 eslint 플러그인
# eslint 와 prettier의 연동을 위해 pnpm add -D prettier eslint-plugin-prettier eslint-config-prettier
Bash
복사

4. 설정

package.json

package.json에 코드추가 - 린트 설정 확인을 위해 주로 사용하는 명령어들 추가
"scripts": { // ...생략 "lint": "eslint './src/**/*.{ts,tsx,js,jsx}'", "lint-fix": "eslint \"**/*.{ts,tsx}\" --ext .ts,.tsx --fix" },
JSON
복사

.eslintrc.js

.eslitrc.js 파일 생성 및 내용 추가
module.exports = { root: true, // TS파일 린팅을 위한 필.수.코.스 parser: "@typescript-eslint/parser", // TS 컴파일러의 API에게 접근하기 위한 코드 parserOptions: { // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment tsconfigRootDir: __dirname, project: ["./tsconfig.json"], }, // 편한 airbnb + ts-eslint 그리고 마지막엔 prettier 순서로 extends extends: [ "airbnb", "plugin:react/jsx-runtime", "plugin:@typescript-eslint/recommended", "plugin:@typescript-eslint/recommended-requiring-type-checking", "plugin:import/typescript", "prettier", ], // ...생략
JSON
복사

번외. 선호하는 rules

module.exports = { parser: "@typescript-eslint/parser", extends: [ "airbnb", "plugin:@typescript-eslint/recommended", "prettier", ], plugins: ["react-hooks", "unicorn"], rules: { "@typescript-eslint/no-explicit-any": "error", "@typescript-eslint/no-unused-vars": "error", "unicorn/no-empty-file": "error", "react/no-unknown-property": ["error", { ignore: ["css"] }], "react/require-default-props": "off", "react-hooks/exhaustive-deps": "error", "react/jsx-props-no-spreading": "off", "react/no-unused-prop-types": "off", "react/function-component-definition": [ "error", { namedComponents: ["arrow-function", "function-declaration"], }, ], "react/jsx-filename-extension": [ "warn", { extensions: [".ts", ".tsx"] }, ], "react/prop-types": "off", "react/react-in-jsx-scope": "off", "react/jsx-key": "error", "import/extensions": ["off"], "import/prefer-default-export": "off", "jsx-a11y/anchor-is-valid": [ "error", { components: ["Link"], specialLink: ["hrefLeft", "hrefRight"], aspects: ["invalidHref", "preferButton"], }, ], "import/no-unresolved": "error", "arrow-body-style": ["error", "as-needed"], "react/destructuring-assignment": ["error", "never"], "no-console": "error", camelcase: "off", }, settings: { "import/resolver": { typescript: {}, }, }, ignorePatterns: [], };
JSON
복사

참조