해당 글은 시리즈로 작성될 예정입니다! React 프로젝트에서 일관성 있는 코드를 유지하기 위해 사용하는 ESLint, Prettier, husky, lint-staged가 무엇인지, 왜 사용하며, 어떻게 사용하는지 알아볼 것이며 아래 순서로 포스팅 될 것입니다. :)
> (1) ESLint와 Prettier가 무엇이며 왜 필요하고 어떻게 사용하는지
(2) 기본적인 ESLint, Prettier config
(3) husky와 lint-staged로 커밋할 때마다 자동으로 lint 검사하기
ESLint와 Prettier는 일정한 규칙에 맞는 코드 퀄리티 및 스타일을 유지할 수 있게 검사해주는 도구이며,
husky와 lint-staged는 그 검사에 통과되지 않은 파일을 git에 commit할 수 없도록 하기 위해 사용한다.
이번 글에서는 ESLint와 Prettier에 대해 알아보겠다.
자바스크립트 코드에서 발견된 문제 패턴을 식별하기 위한 정적 코드 분석 도구이다.
대부분의 프로그래밍 언어에는 컴파일하는 과정에서 수행되는 Linter가 기본적으로 내장되어 있다.
그러나, 인터프리터 언어인 자바스크립트는 Linter가 내장되어 있지 않다.
이 때문에 런타임 환경에서 에러가 발생할 확률이 높다.
따라서 ESLint와 같은 Linting 도구를 사용한다.
Lint란?
소스코드를 분석하여 문법적인 오류나 스타일적인 오류, 적절하지 않은 구조 등에 표시를 달아주는 행위이며, Linter란 Lint의 동작을 도와주는 도구를 말한다.
자바스크립트로 특정 기능을 구현할 때, 그 기능을 구현하기 위해 굉장히 다양한 방식을 사용할 수 있다.
함수를 선언하는 데에도 크게 4가지 방식이 있고, 배열을 순회하기 위해서도 굉장히 다양한 방법을 사용할 수 있다.
// 함수 선언문
function square(number) {
return number * number;
}
// 기명 함수 표현식(named function expression)
const foo = function multiply(a, b) {
return a * b;
};
// 익명 함수 표현식(anonymous function expression)
const bar = function(a, b) {
return a * b;
};
// 생성자 함수
const square = new Function('number', 'return number * number');
console.log(square(10)); // 100
// 화살표 함수
// 매개변수 지정 방법
() => { ... } // 매개변수가 없을 경우
x => { ... } // 매개변수가 한 개인 경우, 소괄호를 생략할 수 있다.
(x, y) => { ... } // 매개변수가 여러 개인 경우, 소괄호를 생략할 수 없다.
// 함수 몸체 지정 방법
x => { return x * x } // single line block
x => x * x // 함수 몸체가 한줄의 구문이라면 중괄호를 생략할 수 있으며 암묵적으로 return된다. 위 표현과 동일하다.
() => { return { a: 1 }; }
() => ({ a: 1 }) // 위 표현과 동일하다. 객체 반환시 소괄호를 사용한다.
() => { // multi line block.
const x = 10;
return x * x;
};
const arr = [0, 1, 2, 3];
arr.foo = 10;
for (const key in arr) {
console.log('key: ' + key, 'value: ' + arr[key]);
}
arr.forEach((item, index) => console.log(index, item));
for (let i = 0; i < arr.length; i++) {
console.log(i, arr[i]);
}
for (const item of arr) {
console.log(item);
}
이처럼 다양한 방식으로 구현할 수 있는 코드 방식을 일관성 있게 구현할 수 있도록 잡아주는 것이 ESLint가 하는 역할이다.
(이 예시는 극히 일부이며 다양한 플러그인을 통해 자바스크립트를 넘어서 React/React Hooks/TypeScript 등 자바스크립트를 기반으로 한 다양한 환경에서의 코드 규칙을 설정할 수 있다!)
깔끔한 코드와 협업을 위해선 일관성 있는 코드 스타일을 유지하는 것이 매우 중요하다.
ESLint가 코드 퀄리티를 일관적으로 유지해준다면,
Prettier는 일관적인 코드 스타일을 유지할 수 있게 도와주는 툴이다.
다시 말해 ESLint는 문법 에러를 잡아주거나 더 좋은 코드 구현 방식을 사용하도록 해주지만, Prettier는 줄 바꿈, 공백, 들여 쓰기 등과 같은 스타일을 교정해준다.
예를 들어 아래와 같은 코드를
function HelloWorld({greeting = "hello", greeted = '"World"', silent = false, onMouseOver,}) {
if(!greeting){return null};
// TODO: Don't use random in render
let num = Math.floor (Math.random() * 1E+7).toString().replace(/\.\d+/ig, "")
return <div className='HelloWorld' title={`You are visitor number ${ num }`} onMouseOver={onMouseOver}>
<strong>{ greeting.slice( 0, 1 ).toUpperCase() + greeting.slice(1).toLowerCase() }</strong>
{greeting.endsWith(",") ? " " : <span style={{color: '\grey'}}>", "</span> }
<em>
{ greeted }
</em>
{ (silent)
? "."
: "!"}
</div>;
}
아래와 같이 잡아줄 수 있다.
function HelloWorld({
greeting = "hello",
greeted = '"World"',
silent = false,
onMouseOver,
}) {
if (!greeting) {
return null;
}
// TODO: Don't use random in render
let num = Math.floor(Math.random() * 1e7)
.toString()
.replace(/\.\d+/gi, "");
return (
<div
className="HelloWorld"
title={`You are visitor number ${num}`}
onMouseOver={onMouseOver}
>
<strong>
{greeting.slice(0, 1).toUpperCase() + greeting.slice(1).toLowerCase()}
</strong>
{greeting.endsWith(",") ? (
" "
) : (
<span style={{ color: "grey" }}>", "</span>
)}
<em>{greeted}</em>
{silent ? "." : "!"}
</div>
);
}
환경은 vscode, CRA, typescript, yarn 전제로 설명하겠다.
둘 다 패키지 설치, vscode extension 설치가 필요하며 각각의 설정 파일을 통해 원하는 코드 구현 방식, 스타일 등을 vscode 상에서 경고/에러 표기를 강제하도록 할 수 있다.
또한 vscode 설정을 통해 가능한 것은 저장할 때마다 강제 수정이 되도록 할 수 있다.
yarn add -D eslint
-D 옵션으로 설치하는 이유
package.json에 개발 시에만 사용하는 개발 의존성(devDependencies)으로 기록되게 된다. 개발 의존성으로 설치된 패키지는 --production 옵션을 통해 운영 버전에서는 설치되지 않게 할 수 있다.
vscode extension 설치
각종 lint 룰 설정을 위해서는 프로젝트 루트 디렉토리에 .eslintrc 파일을 만들어서 작성해줘야 한다.
.eslintrc 파일의 확장자는 js, json, yml로 다양하게 설정할 수 있는데 이 글에서는 json으로 하겠다.
.eslintrc 파일의 구성을 살펴보겠다.
아래는 ESLint 공식 문서의 예시이다.
ESLint 공식 문서의 이 글을 읽어보면 아주 상세히 설명되어 있으니 이 곳을 참고해도 좋다.
{
"root": true,
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended"
],
"parser": "@typescript-eslint/parser",
"parserOptions": { "project": ["./tsconfig.json"] },
"plugins": [
"@typescript-eslint"
],
"rules": {
"@typescript-eslint/strict-boolean-expressions": [
2,
{
"allowString" : false,
"allowNumber" : false
}
]
},
"ignorePatterns": ["src/**/*.test.ts", "src/frontend/generated/*"]
}
lint 설정을 위해 중요한 부분은 plugins
, extends
, rules
인데 다른 부분도 알아두면 좋다.
root
true
이며, 이 값이 true
가 아니면 eslintrc 파일을 찾을 때 상위의 디렉토리까지 검색하게 된다.plugins
plugins
에 추가된다고 해서 바로 적용되는 것은 아니다. 그저 가지고 오겠다는 것이며 extends
나 rules
설정을 해야 적용을 할 수 있다.extends
extends
에 추가해준다.extends
를 통해 plugin을 통째로 가져와 사용한다.extends
옵션을 제공하는 경우가 많은데, recommended/strict/all 등이 있다. plugin의 규칙을 얼마나 어떻게 따를 것인지를 의미하며 보통 recommened를 많이 사용한다. "extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended"
],
parser
yarn add -D @typescript-eslint/parser
rules
이 외에도parserOptions
, env
등을 설정해줄 수 있다.
parserOptions
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": 2020,
"sourceType": "module"
}
env
"env": {
"browser": true,
"node": true
}
"browser": true
를 하게 되면 console.log()
를 에러 없이 사용할 수 있게되고, "node":true
를 하게되면, require
를 에러 없이 사용할 수 있게된다.ESLint를 처음 접한다면 여기까지 읽고도 eslintrc 설정에 대해 잘 이해가 가지 않을 수 있다.
그런 사람들을 위해 다음 글에서 실제로 기본적으로 많이들 쓰는 plugin을 소개하며 더 자세히 다루어볼 예정이다.
yarn add -D prettier
vscode extension 설치
ESLint와 마찬가지로 설정 파일이 필요하다.
prettier의 각종 옵션을 직접 설정할 수 있다.
어떤 옵션이 있는지는 공식 문서의 이곳에서 확인할 수 있다.
{
"printWidth": 100,
"tabWidth": 2,
"semi": true,
"singleQuote": true,
"trailingComma": "all",
"endOfLine": "auto"
}
이또한 더 자세한 내용은 다음 글에서 다루겠다.
vscode 자체에도 prettier 설정을 해줄 수가 있는데 이것은 프로젝트에 공유되지 않으니 prettierrc 파일에 설정을 하는 것이 좋다.
만약 prettierrc 파일이 있다면 우선적으로 그 설정을 따른다.
ESLint의 plugin들의 rule 중 스타일과 관련된 것들도 있기 때문에 종종 Prettier와 충돌하는 일이 생긴다.
이를 방지하기 위해서는 아래 두 가지 plugin을 이용할 수 있다.
설치 및 설정 방법은 아래와 같다.
yarn add -D eslint-config-prettier eslint-plugin-prettier
{
"extends": [
"some-other-config-you-use",
"prettier"
]
}
{
"plugins": ["prettier"],
"rules": {
"prettier/prettier": "error"
}
}
여기까지 설정을 했다면 위에서 설정한 rule들에 어긋나는 코드에 에러/경고 표시가 나게 될 것이다.
그런데 추가적으로 파일 저장 시 어긋난 스타일들을 자동으로 format 해주는 설정을 추가하면 매우 편하다.
이는 vscode의 settings.json에서 formatOnSave를 true로 설정해주면 된다.
때에 따라 formatOnSave가 동작하지 않을 때도 있는데 프로젝트 루트 디렉토리에 .vscode 폴더를 만들고 아래 내용을 settings.json 파일에 넣으면 된다.
.vscode/settings.json
{
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
https://velog.io/@bab_bury/React-ESLint-Prettier-%EC%84%A4%EC%B9%98-%EB%B0%8F-%EC%84%A4%EC%A0%95
https://kimdabin.tistory.com/entry/Reactjs-ESLint%EC%99%80-Prettier%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%9C-React-%ED%99%98%EA%B2%BD-%EC%84%A4%EC%A0%95-VSCode
https://helloinyong.tistory.com/m/325
https://poiemaweb.com/
https://prettier.io/
https://eslint.org/
ESLint와 Prettier를 함께 쓸 수 있어서 ISTJ인 저는 너무 행복하네요..