[Next.js + TS] 초기세팅 - (2) ESLint, Prettier
지난, CRA 초기세팅 및 Typescript 세팅에 이은 2번째 글이다. 주제는 ESLint, Prettier!
뒤에서도 설명하겠지만, 이 툴들은 기능적인 부분보다는 동기들과의 프로젝트 협업을 위한 세팅에 사용되었다.
이들의 역할을 알아보고, 나도 단순히 적용만 하고 지나쳤던 설정들에 대해 자세히 알아보았다.
📓 ESLint
- 개요
ESLint는 Javascript, Typescript 의 코딩 스타일 도구이다. JS코드가 ECMAScript Specification에 부합하는지 검사하는 툴이다.
코딩 스타일 가이드라인을 지정하여, 패턴을 준수하지 않을 경우 사후에 발생할 수 있는 잠재적 문제점을 사전에 방지하기 위해 사용되는 것이다.
* 본래, TS는 TSLint 라는 코딩 스타일 도구가 있었으나, 현재는 ESLint 하나로 모두 linting이 가능 (단, TS는 별도 플러그인 필요)
- 설치 및 적용
먼저, VSCode 기준으로 위 Extension을 설치해준다.
npm i -D eslint
그리고, 프로젝트에서 eslint 설치를 위해 위 커맨드를 입력한다.
이 때, 개발환경에서만 사용하기 위해 -D(development)로 지정한다.
npx eslint --init
다음으로, 프로젝트 루트에서 eslint를 실행시켜준다. 몇 가지 질문들이 나오며, 프로젝트 상황에 맞게 답변하면 된다.
? How would you like to use ESLint?
❯ To check syntax and find problems
? What type of modules does your project use?
❯ None of these
? Which framework does your project use?
❯ None of these
? Does your project use TypeScript?
❯ No
? Where does your code run?
❯ browser
? What format do you want your config file to be in?
❯ JavaScript
이를 마치면, 루트 경로에 .eslintrc.js 파일이 생성된다. 여기서, ESLint 관련된 세부설정이 가능하다.
- 설정 (.eslintrc.js)
{
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 2018, // 최신 문법 지원
"sourceType": "module", // 모듈 시스템 사용시
"ecmaFeatures": {
"jsx": true // 리액트의 JSX 파싱을 위해서
}
},
"plugins": ["react", "@typescript-eslint", "prettier"],
"extends": [
"plugin:react/recommended", // 리액트 추천 룰셋
"plugin:@typescript-eslint/recommended", // 타입스크립트 추천 룰셋
// eslint의 typescript 포매팅 기능을 제거(eslint-config-prettier)
"prettier/@typescript-eslint",
// eslint의 포매팅 기능을 prettier로 사용함. 항상 마지막에 세팅 되어야 함.
"plugin:prettier/recommended" // (eslint-plugin-prettier)
],
"settings": {
"react": {
"version": "detect" // eslint-plugin-react가 자동 리액트버전탐지
},
}
}
위 파일 역시, 내 미니 프로젝트에서 설정했던 ESLint 항목들이다. 간략적인 설명은 주석을 참고 바란다.
대표적인 옵션들에 대해서 이번 기회에 공부 및 아래와 같이 정리해보았다.
1) parser(파서)
ESLint는 구문 분석을 위해 기본적으로 Espree 파서를 사용한다.
이외에도, Babel과 함께 사용되는 babel-eslint, TS 구문 분석을 위해 사용되는 @typescript-eslint/parser 등이 있다.
2) parserOptions(파서 옵션)
ESLint 사용을 위해 지원하려는 Javascript 언어의 옵션을 지정할 수 있다. 버전 및 모듈사용 여부 등을 설정한다.
- ecmaVersion : 사용할 ECMAScript 버전 설정
- sourceType : parser의 export 형태를 설정
- ecmaFeatures : ECMAScript 언어 확장 기능을 설정
- globalReturn - 전역 스코프 사용 여부 (node, common.js 환경에서 최상위 스코프는 module)
- impliedStric - strict mode 사용 여부
- jsx - ECMAScript 규격의 JSX 사용 여부
{
"parserOptions": {
"ecmaVersion": 6,
"sourceType": "module",
"ecmaFeatures": {
"jsx": true
}
}
}
3) plugins(플러그인)
ESLint 문법이 정의된 npm 모듈이다. 통상, eslint-plugin-[플러그인 이름] 으로 명명된다.
4) extends(확장)
extends는 추가한 플러그인을 사용할 규칙을 설정한다.
플러그인은 일련의 규칙의 집합이며, 플러그인을 추가하여도 모든 규칙이 적용되지 않는다.
그렇기에, 플러그인에 속한 규칙을 사용하기 위해 extends에서 설정해줘야하는 것이다.
// 예시) React 플러그인
{
"plugins": [
"react"
],
"extends": [
"eslint:recommended",
"plugin:react/recommended"
],
}
5) rules(규칙)
ESLint에는 프로젝트에서 사용하는 규칙을 수정할 수 있다. 규칙은 기본적으로 아래 옵션과, 추가옵션은 배열 리터럴 구문으로 지정한다.
- "off" 또는 0 : 규칙을 사용하지 않음
- "warn" 또는 1 : 규칙을 경고로 사용
- "error" 또는 2 : 규칙을 오류로 사용
{
"rules": {
// 세미콜론은 사용하지 않으며 사용할시 경고를 띄움
"semi": ["warn", "never"]
// 더블쿼터(")만을 사용하며 백틱(TemplateLiterals)은 허용됨. 어길시 에러를 발생시킴.
"quotes": ["error", "double", { "allowTemplateLiterals": true }]
}
}
6) env(환경)
env는 global 객체를 ESLint가 인식하게 하는 부분으로, 대표적으로 "browser": true 로 설정하면 window 혹은 document 로 할당되는 것이다.
7) settings
모든 규칙에 의해 공유되는 설정을 하는 부분이며, 대표적으로는 절대경로를 src 폴더에서 사용하기 위해 설정하는 경우가 있다.
{
"settings": {
"import/resolver": {
"node": {
"paths": ["src"]
}
}
}
}
8) 기타
* 인라인으로 규칙 비활성화
// 전체 파일 규칙 경고 비활성화, 파일 맨위에 아래 블록 주석 추가
/* eslint-disable */
alert('foo');
// 경고 비활성화 블록 주석
/* eslint-disable */
alert('foo');
/* eslint-enable */
// 특정 규칙 경고 비활성화
/* eslint-disable no-alert, no-console */
alert('foo');
console.log('bar');
/* eslint-enable no-alert, no-console */
* overrides : 파일 그룹에 대해서만 규칙 비활성화
{
"rules": {...},
"overrides": [
{
"files": ["*-test.js","*.spec.js"],
"rules": {
"no-unused-expressions": "off"
}
}
]
}
* 파일 디렉토리 제외 : ignorePatterns 필드에서 설정하거나, .eslintignore 파일을 작성하여 파일 및 디렉토리 제외
// .eslintrc 파일 ignorePatterns 설정
{
"ignorePatterns": ["temp.js", "node_modules/"],
"rules": {
//...
}
}
//.eslintignore 파일 생성
/root/src/*.js
.eslintignore 를 현재가 아닌 다른 디렉토리에서 제외파일을 사용하려면, --ignore-path 옵션을 사용할 수 있다.
eslint --ignore-path .gitignore file.js
* 구성 파일 사용
ESLint는 루트 디렉토리까지 구성파일을 찾는다.
특히, .eslintrc 와 package.json 파일이 같은 디렉토리에 있다면, .eslintrc가 우선순위를 가지므로 아래처럼 선언한다.
// package.json
eslintConfig = {
root: ture,
...
}
// .eslintrc.*
{
root: true,
...
}
📓 Prettier
- 개요
Prettier는 Code Formatter 이다. 코드를 정리할 때, 일정한 형식으로 맞춰주는 툴인 것이다.
문법적인 부분보다는, 개발자들간의 협업을 할 때 코드 스타일이 분화되는것을 최소화하기 위한 목적이 크다.
- 설치 및 적용
마찬가지로, VSCode Extension을 설치해준다.
npm i -D prettier
// Prettier 및 Plugin 설치
npm i -D prettier eslint-config-prettier eslint-plugin-prettier
프로젝트에서 Prettier를 설치를 위해 위 커맨드를 입력한다.
마찬가지로, 개발환경에서만 사용하기 위해 -D(development)로 지정한다.
마찬가지로, 프로젝트 루트 디렉토리에 .prettierrc 파일이 생성되며, 여기서 세부적인 설정이 가능하다.
- 의존성 설치 및 .eslintrc 적용
마지막으로, ESLint와 혼용해서 사용하는 경우 충돌방지를 위해 위같이 의존성을 설치해준다.
npm i -D eslint-plugin-prettier eslint-config-prettier
- eslint-config-prettier : 불필요하거나 Prettier과 충돌할 수 있는 모든 규칙을 비활성화
- eslint-plugin-prettier : 코드 포매팅 시 Prettier를 사용하게 만드는 규칙 추가
module.exports = {
root: true,
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint', 'prettier'],
extends: ['standard-with-typescript', 'prettier', 'plugin:prettier/recommended'],
parserOptions: {
project: './tsconfig.json',
},
rules: {
'@typescript-eslint/semi': 'off',
'@typescript-eslint/space-before-function-paren': 'off',
},
};
이를 위처럼 .eslintrc에 반영하면 된다. 이래도 충돌하는 경우, rules에서 해당 속성을 off 처리하면 된다.
- 설정(.prettierrc)
{
"singleQuote": true,
"semi": true,
"useTabs": false,
"tabWidth": 2,
"trailingComma": "es5",
"bracketSpacing": true,
"jsxBracketSameLine": false,
"arrowParens": "always"
}
마찬가지로, 내 프로젝트에서 사용한 .prettierrc 파일이다.
semi, jsxBracketSameLine 등은 디폴트 값이나, 많이 설정되는 옵션들에 대해 같이 작업하는 동료들에게 의미를 명시하기 위해 주석을 첨부하고자 해당 코드를 추가했다.
* 전체 옵션
{
"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, Prettier 모두 프로젝트의 기능적으로 이점이 되는 툴보다는, 협업에 의의가 있는 툴이다.
그렇기에, 대충 default 세팅만 가져가고 신경쓰지 않곤 했는데, 그 의미를 이번 기회에 명확하게 알고 정리하게 되었다.
이전 팀 프로젝트 떄, 단순히 Airbnb 린트만 가져왔을 떄 적용이 안 된 이유를 이번에 깨닫게 되었다.
(아마, 당시에 구체적으로 extends를 설정하지 않아 내 VSCode 에서 적용되지 않았던 것 같다.)
또한, ESLint는 JS파서도 적용하므로, 프로젝트가 Next.js, TS 등 어떤 환경을 쓰는가에 따라 적정한 파서를 설정하는 것 역시 신경써야함을 느꼈다.
다음 3번째 포스팅은 Babel에 대해 진행하려고 한다.
모듈 import 절대경로 설정, Next.js SSR 시 Styled-Components 초기 스타일링을 위해 설정한 Babel을 정리해보겠다!
[참고]
- [초기세팅 전체] junghyeonsu 님의 블로그 : https://velog.io/@junghyeonsu/React-create-react-app-Typescript-%EC%B4%88%EA%B8%B0-%EC%84%B8%ED%8C%85-%EC%99%84%EB%B2%BD-%EC%A0%95%EB%A6%AC
- [초기세팅 전체] miiunii 님의 블로그 : https://velog.io/@miiunii/CRACreate-React-App%EC%9C%BC%EB%A1%9C-Typescript-%EC%84%A4%EC%A0%95%ED%95%98%EA%B8%B0
- [ESLint] kyusung 님의 블로그 : https://velog.io/@kyusung/eslint-config-2
- [ESLint] rexiann 님의 블로그 : https://rexiann.github.io/2020/12/13/what-is-eslint.html
- [Prettier] seonghui 님의 블로그 : https://seonghui.github.io/blog/2020/12/27/typescript-eslint-prettier/