영양제 쇼핑몰을 만드는 프로젝트에서 ESLint Prettier를 굉장히 유용하게 사용했기 때문에 이번 Portfolio 에서도 사용하고자 설정했다.
프로젝트를 Next.js로 제작했눈데, Next.js에서는 별도의 설치 없이 Eslint를 제공한다!
Next.js provides an integrated ESLint experience out of the box.
= Next.js는 별도의 설치 없이도 완성된(통합된?) ESLint를 제공합니다
(https://nextjs.org/docs/basic-features/eslint)
그럼 이제 eslintrc.json
을 조금 손봐주자..
한 프로젝트 안에서 여러 ESLint 설정을 할 수 있다. 한개의 레포지토리에서 여러개의 프로젝틀르 수행할 때 ESLint설정이 여러개가 필요하다.
ESLint는 적용 대상에 설정 파일이 있는지 찾아보고 없다면 디렉터리를 위로 수색한다(like 스코프체인). root 옵션은 이 설정이 true
로 되어있을 경우 더이상 올라가지 않도록 만들어준다.
Portfolio 프로젝트외에 다르프로젝트는 없지만, 혹시 다른 상위 폴더에 영향이 갈까봐 true
로 설정했다.
"root": true,
ESLint가 최신 문법으로 코드를 린트할 수 있게끔 파서를 설정해주는 옵션. 나는 타입스크립트 프로젝트니께 @typescript-eslint/parser
사용.
"parser": "@typescript-eslint/parser",
(https://eslint.org/docs/latest/use/configure/parser)parserOptions
사용할 언어에 대한 설정. ESLint에서는 기본적으로 ECMAscript5 구문을 사용한다. 근데 그럼
let
이나const
가 막히잖아? 바꿔준다.
"parserOptions": {
"project": "./tsconfig.json",
"createDefaultProgram": true
},
project: ./tsconfig.json 을 프로젝트의 설정 파일로 설정해 ESLint에서 typescript를 분석할 때 해당 파일을 참조해 분석한다.
createDefaultProgram: parser에서 설정한 @typescript-eslint/parser을 위한 옵션인 듯 하다..?ESLint가 TypeScript 파일을 분석할 때 TypeScript 컴파일러 API를 사용하여 TypeScript 프로그램을 생성한다.(https://typescript-eslint.io/architecture/parser/)
(https://eslint.org/docs/latest/use/configure/language-options)
ESLint가 사용하는 환경을 지정해서 해당 환경에서 사용되는 전역 객체, 변수, 함수 등을 지정할 수 있다.
"env": {
// 전역객체를 eslint가 인식하는 구간
"browser": true, // document나 window 인식되게 함
"node": true,
"es2020": true
}
browser의 전역 객체들을 사용할 수 있게 하고(window, document 등) Node.js의 환경 전역 객체인 global, process등도 사용할 수 있게 해준다. 또한 es2020에서 추가된 기능들을 지원할 수 있게 설정했다
(https://eslint.org/docs/latest/use/configure/language-options)
ESLint 설정이 미적용 될 폴더와 파일 설정
"ignorePatterns": ["node_modules/"],
node_module 안되게 해주기..되면 클남
(https://eslint.org/docs/latest/use/configure/ignore)
기본 규칙 말고도 추가 규칙을 적용시켜 ESLint를 확장시킬 수 있다. airbnb의 룰이 유명하다(깃헙에 가면 룰을 확인할 수 있다).
우선 관련 의존성 패키지들을 확인하고 설치해준다.
npm info "eslint-config-airbnb@latest" peerDependencies
{
eslint: '^7.32.0 || ^8.2.0',
'eslint-plugin-import': '^2.25.3',
'eslint-plugin-jsx-a11y': '^6.5.1',
'eslint-plugin-react': '^7.28.0',
'eslint-plugin-react-hooks': '^4.3.0'
}
해당 패키지들도 설치..인데 typescript버전도 설치해줘야함.
npx install-peerdeps --dev eslint-config-airbnb
한꺼번에 종속패키지까지 설치해주고,
npm install -D eslint-config-airbnb-typescript @typescript-eslint/eslint-plugin @typescript-eslint/parser
타입스크립트 패키지들까지 설치해줌
"extends": [
"airbnb",
"airbnb-typescript",
"airbnb/hooks",
"next/core-web-vitals",
"eslint:recommended",
"plugin:@typescript-eslint/recommended", // ts 권장규칙
"plugin:prettier/recommended", // eslint의 포매팅을 prettier로 사용.
"prettier" // eslint-config-prettier prettier와 중복된 eslint 규칙 제거
]
(https://eslint.org/docs/latest/use/configure/plugins, https://github.com/airbnb/javascript/tree/master/packages/eslint-config-airbnb)
사실상 ESLint의 핵심. 코드가 특정 조건에 만족하는지, 만족하지 못한다면 어째야 할지를 정한다. 그 룰에 대한 추가 옵션이 필요할지도 모른다. ESLint에서 제공하는 기본 빌트인 룰(https://eslint.org/docs/latest/rules/)도 많고, 추가할수도 있다. 또한 extends에서 설정한 룰에 대해서 여기서 바꿔줄수도 있다. rules에서 설정한 옵션은 extends에서 가져온 옵션설정들보다 우선한다.
단계는
각각 0, 1, 2로 치환해서 쓸 수 있다.
"rules": { "react/react-in-jsx-scope": "off", // react 17부턴 import 안해도돼서 기능 끔 // 경고표시, 파일 확장자를 .ts나 .tsx 모두 허용함 "react/jsx-filename-extension": [ "warn", { "extensions": [".js", ".jsx", ".ts", ".tsx"] } ], "no-useless-catch": "off", // 불필요한 catch 못쓰게 하는 기능 끔 "react/prop-types": 0, // props의 유효성 검사..끔.. typescript 쓸거니까 "react/require-default-props": "off", // props의 기본값 설정. 껐다. "react/jsx-props-no-spreading": 0, props로 받은 친구를 spread할 수 있을지. 된다. "@typescript-eslint/no-use-before-define": 0, // 정의 전에 사용. 가능 "no-param-reassign": 0, // 함수 매개변수를 다른 겂으로 재할당 하는 것을 방지할지. 끔. "@typescript-eslint/no-empty-interface": 0 // interface가 빈 것을 허용할지 안할지? 허용 함 }
공유되는 설정. 모든 규칙에서 공유해야하는 설정이다.
"settings": {
"import/resolver": {
"node": {
"extensions": [".js", ".jsx", ".ts", ".tsx"]
}
}
}
import/resolver는 모듈을 가져올 때 경로를 해석하는 방법을 지정한다. 위 설정은 ".js", ".jsx", ".ts", ".tsx"파일을 모듈로 가져올 때, 확장자를 생략해도 정상적으로 모듈 경로를 해석하도록 지정한 것이다.
{
"semi": false, // 세미콜론 꺼주기
"singleQuote": true, // ''사용
"useTabs": true, // 탭 사용 허용
"tabWidth": 2, // 탭은 2간 띄어쓰기와 같음
"trailingComma": "all", // 배열과 객체 맨 마지막 요소 뒤에 ,
"printWidth": 80, // 한 줄의 최대 넓이
"arrowParens": "avoid" // 화살표 함수에서, 인자가 하나밖에 없을 때 () 생략할수 있음
}
진짜 너무너무너무 어려웠다..... 도중에 작동을 안하는 것 같아서 하루종일 붙잡고 있다가, vscode를 한번 껐다가 켜보니까 또 적용이 됐다🤔 그래도 한번 정리하려고 했는데, 이번 기회에 사용하게 되어서 다행이다....
위 설정들은 바뀔 수 있다. 하다가 가독성이 좀 떨어지거나 불편한데? 싶으면 당연히 수정이 들어갈 것.
그래도 프로젝트에서 좀 더 깔끔한 코드를 작성할 수 있다는 점에 매우 만족한다!!!