ESLint, Prettier Setting, 헤매지 말고 정확히 알고 설정하자.
ESLint, Prettier 관련해서 환경 세팅을 하면 항상 어쩔 땐 잘되고, 어쩔 땐 안되고...
구글링하면 그렇게 많이 나오는 방식들을 전부 해봐도 계속 안돼서 시간을 그렇게 버릴 때가 많았던 것 같다.
그냥 생각없이 Prettier extension 설치해라, eslintrc 이렇게 세팅해라, 등등.. 따라 하니까 꼬이기도 하고, 저장을 시도하면 자동 수정은 안되고.. 그럴 때마다 속이 터졌는데, 이참에 아예 작정하고 시간 내서 제대로 파악 좀 해봤다.
아마 나처럼 하라는 대로 했는데도 왜 안되는지 궁금할 개발자들이 있지 않을까 싶다.(나만 그런걸까...)
직접 그 원인을 상세히 파악하고 알아보도록 하자.
VSCode가 코드의 Lint Error를 잡는 것부터, 저장 시 자동 수정하는 설정까지.. 그 복잡한 조건이 대체 무엇인지!
이 글은 eslint, prettier 설정법보다는, eslint와 prettier가 VSCode 내에서 어떻게 설정되고 융합이 되어서 돌아가는지를 초점에 맞춰서 작성된 글입니다. 단순히 lint와 prettier 설정법만 알고자 하신다면 다른 블로그 글을 참고하시는 것을 추천드립니다.
ESLint와 Prettier
우선 ESLint와 Prettier의 차이를 정확하게 알아보자.
대부분 개발자들은 eslint만 사용하지 않고 prettier를 함께 사용한다.
둘 다 코드 컨벤션을 잡아주는 녀석인데, 그럼 하나만 쓰면 되지 왜 둘을 같이 사용하는 걸까?
분명 다른 차이가 있으니 같이 사용하는 것임이 분명하다.
(난 지금까지 prettier가 코드 파일 저장할 때 알아서 컨벤션에 맞게 정리 후 저장해주는 건 줄 알았다...-.-)
다른 블로그들을 봐보니 대부분 설명이 아래처럼 비슷하게 소개하고 있다.
"eslint는 코드 퀄리티를 보장하도록 도와주고, prettier는 코드 스타일을 깔끔하게 혹은 통일되도록 도와준다."
난 처음에 이 말이 무슨 뜻인지 이해를 하지 못했다.
코드 스타일이 깔끔하게 통일되면 그게 곧 코드 퀄리티를 보장해 주는 것 아닌가?라고 생각이 들었다.
그래서 직접 둘의 차이를 정확히 알아봤다.
ESLint
개발 중 특정 기능을 구현할 때, 그 기능을 구현하기 위한 엄청나게 많은 방식이 있다.
// function 키워드 사용
function foo() {
...
}
// arrow function 사용
const foo = () => {
...
}
const Temps = [1,2,3,4,5];
// for문 사용
for(let i = 0; i < Temps.length; i++){
...
}
// Array 내장 함수 사용
Temps.forEach((temp) => {
...
})
예를 들어 함수 정의할 때, 일반 function 키워드의 함수로 정의할 수도 있고, arrow function을 쓸 수도 있다.
또 배열의 반복문을 돌릴 때 일반 for문을 돌릴 수도 있지만, forEach, map 등 Array 내장 함수를 사용할 수도 있다.
이처럼 여러 방식의 코드 작성법이 있는데, 이러한 방식을 일관성 있는 방식으로 구현할 수 있도록 잡아주는 것이 eslint가 하는 역할이다.
prettier
prettier는 eslint처럼 '코드 구현 방식'이 아닌, 줄 바꿈, 공백, 들여 쓰기 등 에디터에서 '텍스트'를 일관되게 작성되도록 도와주는 것이다.
const foo = () => {
const a = [1, 2, 3]; // 스코프 내부 작성 시 두 공백 들여쓰기
}
// <= 빈 줄이 한 줄 이상 안됨.
foo();
그럼 이 둘의 차이를 정확히 인지하고, 이제 eslint와 prettier를 내 프로젝트 환경에 어떻게 세팅되는 건지 알아보자.
ESLint 세팅
우선 ESLint를 쓰려면 당연히 ESLint를 설치해야 된다.
$ npm install -D eslint
// or
$ yarn add -D eslint
근데 eslint만 설치했다고 해서 바로 사용할 수 있는 것이 아니라, eslint extension을 무조건 설치를 해주어야 한다.
ESLint Extension의 설명에도 보면, 해당 워크스페이스(여기서는 해당 프로젝트)에서 eslint가 설치되어 있는지 확인해보고, 없으면 글로벌 eslint를 참조한다고 나와있다. 그리고 필요에 따라 .eslintrc 파일이 필요할 수도 있다고 설명되어 있다.
그렇다.. eslint가 프로젝트 코드 단에서 사용하는 것이 아니라, 해당 VSCode라는 에디터에 적용해서 사용하는 것이다 보니, eslint를 사용하려면 eslint extension만 설치하거나, eslint library만 설치하는 것이 아니라, 둘 다 설치 및 세팅이 되어 있어야 하는 것이다.
이제 이 eslint를 제대로 설치해주었으면, .eslintrc 파일을 통해서 lint rule을 세팅해주어야 한다.
그럼 eslintrc가 어떻게 구성이 되는 건지 한번 알아보자.
.eslintrc
우선 eslint Doc에 나와있는 example은 아래와 같다.
{
"root": true,
"plugins": [
"@typescript-eslint"
],
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended"
],
"parser": "@typescript-eslint/parser",
"rules": {
"@typescript-eslint/strict-boolean-expressions": [
2,
{
"allowString" : false,
"allowNumber" : false
}
]
}
}
root
default는 true인데, 이 값이 true가 아니면, eslintrc 파일을 찾을 때, 해당 프로젝트 디렉토리 뿐 아니라, 내 PC의 root 파일 시스템 root 디렉토리까지 eslint를 찾는다.
plugins
우선 plugin 종류는 여러 가지 있는데, 예를 들어
- eslint-config-airbnb-base: 에어비엔비 린트 플러그인
-
eslint-config-next: Next.js 전용 린트 플러그인
-
eslint-plugin-react: 리액트 전용 플러그인
-
eslint-plugin-prettier: 린트 위에 사용할 프리티어 플러그인
-
eslint-config-prettier: 요건 린트 설정과 중복되는 부분이 있으면 프리티어 룰에서 제외하는 플러그인
- @typescript-eslint/eslint-plugin: : 타입스크립트 전용 린트
대충 이러한 플러그인들이 있다. 이것들 말고도 종류는 훨씬 많다.
프로젝트에 필요로 한 각 플러그인은 npm이나 yarn을 통해서 설치하면 된다.
만약 위에 @typescript-eslint/eslint-plugin을 쓸 거면, eslintrc 파일의 plugins 배열에 해당 모듈에서 제공하는 @typescript-eslint를 장착시키면 되고, 다른 모듈도 같이 쓸 거면 배열에 같이 추가하면 된다.
parser
각 코드 파일을 검사할 파서를 설정하는 부분이다. 기본 설정은 espree이고, 특정 @typescript-eslint/eslint-plugin처럼 특정 플러그인을 사용한다면 해당 플러그인에서 제공하는 parser를 장착하면 된다.
extends
eslint rule 설정이 저장되어 있는 외부 file을 extends 하는 부분이다.
위에 .eslintrc처럼 extends에 eslint:recommended, plugin:@typescript-eslint/recommended를 장착시켜주면, 사용하려는 해당 플러그인에서 기본적으로 제공하는 rule set이 적용된다.
변경하고 싶은 부분이 있다면 rules 쪽에서 커스터마이징 하면 된다.
rules
이쪽은 직접 lint rule을 적용하는 부분이다.
extends로 자동으로 설정된 rules 중에, 특정 rule을 끄거나, erorr를 warning으로 나오도록 변경하는 등 설정을 바꿀 수 있다.
이러한 각 플러그인에 대해 eslintrc에 어떻게 설정을 해야 하는지는, 각 eslint 플러그인 docs를 보면 상세하게 나와있다..(하하.. 그냥 애초에 docs를 열심히 볼걸..)
예를 들어 @typescript-eslint 플러그인의 docs를 들어가 보면, 아래처럼 적용하는 법을 잘 알려준다.
$ npm install --save-dev eslint typescript @typescript-eslint/parser @typescript-eslint/eslint-plugin
// .eslintrc
{
"root": true,
"parser": "@typescript-eslint/parser",
"plugins": [
"@typescript-eslint"
],
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended"
]
}
위 내용들을 다시 정리해보면, 우리가 npm, yarn으로 설치한 eslint과 VSCode Extension의 eslint는 그냥 린트 환경을 세팅해주는 모듈(자체적으로 어느 정도 lint rule을 제공하긴 함)이다.
그리고 실제로 코드를 검사하는 것은, 돌리고 싶은 린트 플러그인을 별도로 설치해서 eslintrc 파일에 장착을 시켜주어야 하는 것이다.
여기까지 VSCode에 ESLint 세팅이 어떻게 되는 것인지 알아봤고, 다음은 Prettier를 알아보자.
Prettier
Prettier를 세팅하는 방법은 2 가지가 있다.
- 별도의 prettier 관련 플러그인을 npm, yarn으로 설치하지 않고 VSCode의 extension을 설치.
- prettier 플러그인을 직접 설치 후 eslintrc에 세팅.
1 번째 방법은 프로젝트 자체에 prettier 룰을 세팅하는 것이 아니라, eslint처럼 현재 내가 쓰고 있는 VSCode 에디터 자체에 prettier rule을 세팅하는 것이다. 따라서 내 환경의 VSCode에서만 해당 prettier 방식이 적용되는 것이다.
반대로 2번째는 프로젝트 자체에 prettier rule을 세팅한 것으로, 해당 프로젝트를 다른 환경에서 돌려도 동일하게 prettier rule을 적용해서 사용할 수 있는 방식이다.
우선 상대적으로 쉬운 첫 번째 방법부터 먼저 알아보자.
VSCode Extension: Prettier - Code formatter
Prettier-code formatter는 설치하는 순간 바로 적용된다.
해당 prettier에 대한 상세 설정 방식은 docs에 들어가면 설명이 아주 잘 나와있다.
command + shift + p를 누르면 나타나는 검색 창에, Open User Settings로 들어가서 prettier를 검색하면, prettier 관련 설정할 수 있는 리스트들이 나타난다. 여기서 여러분들 입맛에 맞게 설정하면 적용된다.
그런데 여기서 궁금한 게 있을 것이다.
어느 글에서는 VSCode의 settings에서 설정하라고 하고, 어디에서는 .prettierrc 파일을 만들라고 되어있는데, 요건 또 어떻게 다른 걸까?
우선 VSCode Settings는 현재 내 PC의 VSCode 환경에 대한 세팅이기 때문에, VSCode Extension으로 설치한 prettier 플러그인에만 적용이 가능하고, npm이나 yarn으로 설치해서 세팅한 prettier 플러그인에는 적용되지 않는다.
따라서 yarn, npm으로 prettier를 설치했다면, .prettierrc 파일을 꼭 이용해야 한다.
그리고 적용 우선순위가 다른데, Prettier를 VSCode Extension으로 설치했다면, VSCode Settings의 prettier에서도 설정할 수 있고, .prettierrc 파일로도 설정이 가능하지만, .prettierrc 파일이 있으면 VSCode Settings의 설정은 무시되고 .prettierrc 파일로 룰이 적용된다.
Prettier 직접 설치
이번엔 Prettier 플러그인을 직접 npm, yarn으로 설치 후 세팅하는 방법을 알아보자. 요것도 역시나 prettier Docs를 보면 사용법이 상세하게 나와있다.
우선 prettier를 설치하자.
$ npm install -D prettier
// or
$ yarn add -D prettier
Docs를 보면, eslint를 사용하면, eslint-config-prettier를 설치해서 세팅하라고 알려주고 있다.
eslint-config-prettier가 무엇을 하는 녀석인지 확인해보자.
eslint-config-prettier
이 글로만 읽으면 정확히 무엇을 하는 친구인지 이해하기 힘든데, 우선 eslint와 중복되는 규칙을 prettier 쪽에서 알아서 꺼주는 역할을 한다고 한다.
해당 플러그인이 eslint 모듈 중 어떤 부분과 관련된 부분을 끄는지 보여준다. 그런데 아래에 eslint-plugin-prettier라는 게 있다?
요것도 무엇인지 한번 봐보자.
eslint-plugin-prettier
코드 내에서 prettier에 걸린 부분들을 린트 에러로 걸린 것으로 보고하도록 하는 플러그인인 것을 알 수 있다.
정확히는 모르겠지만 아마 prettier 룰에 맞지 않는 부분을 에러로 파악하기 위한 설정 같다.
.eslintrc 파일에 어떻게 설정해야 할지 자세히 설명해주고 있다.
"plugin:prettier/recommended"를 extends 하면, 아래처럼 확장 설정이 되는 것을 알 수 있었다.
// .eslintrc
{
"extends": ["prettier"],
"plugins": ["prettier"],
"rules": {
"prettier/prettier": "error",
"arrow-body-style": "off",
"prefer-arrow-callback": "off"
}
}
- "extends": ["prettier"]: eslint-config-prettier를 실제로 활성화시켜서 중복되는 룰을 끄도록 하는 설정.
- "plugins": ["prettier"]: prettier 플러그인 등록하는 설정.
- prettier/prettier: "error": eslint 내에서 prettier가 돌아갈 때, prettier 규칙에 맞지 않는 요소들을 error로 판단하도록 하는 설정.
- "arrow-body-style": "off", "prefer-arrow-callback": "off": eslint와 같이 사용하는 부분에 있어, 내부적인 이슈가 있어서, 임의로 두 설정을 꺼야 함.
위 설정들을 하나하나 해줄 필요 없이, 아래처럼 한 번에 설정하면 된다.
// .eslintrc
{
"extends": ["plugin:prettier/recommended"]
}
이제 상세한 prettier rule 세팅은 root 디렉토리의 .prettierrc 파일이 있는지를 찾고, 해당 파일의 rule을 이용하게 된다.
(.eslintrc 자체에도 선언할 수 는 있으나, 가독성을 위해 .prettierrc로 분리해서 하는 것을 권장.)
여기까지 Prettier 세팅에 관련돼서 정리해 보았다.
여기까지 설정이 되었으면, 코드 내에서 lint와 prettier rule에 맞지 않는 코드 상태가 있으면 eslint error로 판단하고 빨간 줄을 보여주게 되지만, 여러분들이 원하는 "format on Save(저장 시 알아서 수정해주는 기능)"은 아직 동작하지 않을 것이다.
그럼 이 eslint가 세팅된 환경에 format on Save 기능을 어떻게 연동시키게 되는 것일까?
생각보다 간단하다.
VSCode Settings.json
저장 시 자동으로 린트를 잡아주는 기능은 VSCode 에디터가 동작하도록 하는 기능이다. 그래서 VSCode Setting에서 설정을 해주어야 한다. command+shift+p로 나온 검색창에 Open Settings.json(JSON)을 선택하면 Settings 설정이 JSON 형식으로 나온다.
여기서 자동 저장 기능을 설정하는 옵션이 두 가지가 있다.
editor.codeActionsOnSave
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
네이밍만 봐도, save 할 때 코드를 동작시키고 그 동작은 'eslint 관련 요소들을 전체적으로 fix'인 것을 알 수 있다.
코드 단에서 eslint rule에 의해 error로 판단되는 부분들을 lint rule에 맞게 알아서 수정을 해주는 설정이다.
editor.formatOnSave
{
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
위 설정은, save 할 때 VSCode Extension으로 설정된 prettier 환경에 맞게 코드를 수정해주는 옵션이다.
앞 단의 방법과 다르게 eslint 에러를 보고 수정하는 것이 아니라, 에디터에 올라와 있는 텍스트들을 prettier rule에 맞게 정리하는 초점으로 생각하면 된다.
내 경험 상, 여기저기 블로그와 stack overFlow에 format on Save not working 관련 답변들을 보면, 이것 추가해라 저것 추가해라 엄청 많이 봤던 것 같은데, 그냥 format on Save 기능이 동작하지 않는 것은 onSave 기능이 어느 부분이 린트 에러나 prettier 룰에 맞지 않은 것인지를 알지 못해서 동작을 안 하는 것이다.
번외로, 가끔 아래와 같은 설정을 하라고 알려주는 블로그도 있는데,
{
"javascript.format.enable": true,
"typescript.format.enable": true,
}
이건 VSCode 에디터 자체에서 javascript 혹은 typescript의 내장된 포맷터 형식을 사용할지에 대한 설정이다.
따라서 요건 실제로 자동 저장 기능이 동작하지 않는 것과 상관이 없다.
그러니 onSave 기능이 제대로 동작하지 않으면, VSCode Settings.json 파일의 설정을 건드리지 말고, eslint, prettier 세팅을 다시 한번 확인하자.
정리하며
위 내용들을 쭉 정리하면 아래와 같다.
ESLint
eslint 기능 자체는 VSCode 에디터에 적용하는 것이므로, VSCode extension Plugin이 꼭 설치되어야 한다.
Prettier
prettier 세팅 방식은 두 가지가 있다.
첫 번째는 eslint처럼 VSCode 에디터 자체에 적용하도록 Prettier용 VSCode Extension을 설치하는 방식.
두 번째는 prettier 플러그인을 설치 후 eslint 환경에 접목시키는 방식.
Format on Save
"format on Save(저장 시 알아서 수정해주는 기능)"은 두 가지가 있다.
첫 번째는 코드 내 lint error를 발견하고 수정해주는 옵션.
두 번째는 코드 텍스트들을 VSCode Extension으로 설치한 prettier 포맷에 맞게 수정해주는 옵션.
이제는 제대로 알고 설정하자.. 🙇♂️
[22.04.05 추가 내용 - 유의사항]
eslint ver.8 부터 prettier 관련 세팅이 제대로 동작하지 않습니다. 원인은 아직 파악 중...
해당 환경 세팅을 하시려면 eslint ^7로 설치하시길 바랍니다.