ESLint, TSLint, Typescript-ESLint 무엇을 선택해야는가

ESLint, TSLint, Typescript-ESLint 무엇을 선택해야는가

Introduce 🛫

최근에 Flutter로 한동안 개발하다가 다시 react + typescript로 웹개발을 시작하게 되었다. React를 하지 않는동안 생각보다 많은 변화가 있었다. 나는 개발을 시작하기 전에 개발에만 집중 할 수 있도록 미리 tool들과 환경세팅을 하는 것을 중요하게 생각하고, linter 설정을 잘 해두는 것이 개발효율을 높여준다고 생각하기 때문에 새로운 프로젝트를 할때 신경을 쓰려고 한다.

그런데 다시 돌아오고나니 ESLint, TSLint 심지어 Typescript - ESLint가 있다. 여러 블로그를 참고해서 세팅은 했는데.. 패키지는 왜이렇게 많이 설치해야하며 각각 무슨일을 하는지도 모른체 설치했다. 도대체 뭘 골라서 설치해야하지?!


ESLint? 🤔

ESLint는 javascript code를 위한 linter이다. 다른 Linter들도 있지만, ESLint는 여러 styke애 대해 configure 하기가 쉽고, 다른 플러그인을 붙이기도 편하며, 나만의 eslint rule을 sharable configs로 만들어어서 npm을 통해 공유할 수 있어 현재 많이 쓰이고 있는 추세이다.

간단하게 ESLint의 동작 방식에 대해 알아보자.

  1. Javascript code를 parser를 통해서 AST로 변환을 하게 된다.
    • AST는 프로그래밍 언어 문법에 따라 소스 코드 구조를 표시하는 정보를 담은 Tree다.
1
2
3
function printTips() {
tips.forEach((tip, i) => console.log(`Tip ${i}:` + tip));
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
{
"type": "Program",
"body": [
{
"type": "FunctionDeclaration",
"id": {
"type": "Identifier",
"name": "printTips",
"range": [
9,
18
],
"loc": {
"start": {
"line": 1,
"column": 9
},
"end": {
"line": 1,
"column": 18
}
}
},
"generator": false,
"expression": false,
"async": false,
"params": [],
"body": {
"type": "BlockStatement",
"body": [
{
"type": "ExpressionStatement",
"expression": {
"type": "CallExpression",
"callee": {
"type": "MemberExpression",
"object": {
"type": "Identifier",
"name": "tips",
"range": [


  • 첫번째 블록과 같은 코드가 있을 때, 이걸 두번째 블록과 같은 메타 데이터를 담은 tree형태의 데이터 구조로 변경시켜 준다.
  • ESLint는 기본적으로 Espree 라는 parser를 사용하며, babel-eslint 또는 Esprima와 같은 parser로 변경할 수 있다.
  • AST explorer 여기서 직접 AST가 만들어 지는 것을 확인할 수 있다.
  1. 위와 같은 AST 데이터는 lint 관련 plugin들에서 쓰이며, 세팅된 configure에 따라 warning을 주거나, fix를 해준다.

Typescript? 🤔

Typescript-ESLint에서 ESLint는 알겠는데 typescript는 무엇인가? Typescript는 Javascript라는 language의 상위 레이어에서 추가적인 문법을 가지고 Javascript code에 대한 정적 분석을 하는 parser이다.

Typescript의 동작 방식

  1. Typescript를 parser라고 하는 점에서 눈치 챘듯, ESLint 내부에 있는 parser와 같이 Typescript도 source code를 AST로 변환한다.

  2. AST 데이터는 typescript의 다른 compiler 에서 쓰이며 error를 뱉거나 refactor를 쉽게 해준다.

그렇다면, Typescript-ESLint는 왜 만들었는가?
위에서 설명했듯, typescript와 eslint는 둘 다 source code를 AST로 변환한다. 하지만 AST라는 구조만 동일한것이지 디테일하게 보면 각각이 다른 AST를 사용한다고 볼 수 있다.

즉 Typescript-ESLint는 typescript와 eslint의 다른 AST format을 parsing하여 원래 javascript linter인 eslint를 typescript에서도 쓸 수 있게 하기 위한 프로젝트 이다. (이전에 잘 만들어 두었던 것을 재사용할수 있겠죠?!)

TSLint는 왜 deprecated…?
TSLint는 ESLint와 같은 레벨의 프로젝트로써 ESLint가 javascript code를 lint check 하는 것 처럼 typescript에 특화되어서 typescript code만를 lint하는 linter이다.

TSLint는 typescript에 특화되어있다보니 eslint가 javascript ecosystem에서 잘 구축해놓은 system과 code들을 재사용하지 못하고 독자적으로 따로 구현을 해야하는 이슈가 존재했다

따라서 TSLint는 결국에 deprecated 되었고 eslint 에서는 tslint를 eslint로 migration하는 툴을 제공하고 있다.


ESLint를 적용하기 전에…

그러면 ESLint환경에서 typescript-eslint만 설치하면 되느냐? 그것도 아니다. typescript-eslint하나만 존재하는 것이 아니라 @typescript-eslint/eslint-plugin, @typescript-eslint/parser등 관련 플러그인을 깔아야 한다. 왜 이렇게 verbose 하게 여러 패키지를 import 하도록 구성해놨을까?

이전에 설명했던 내용으로 돌아가면 Typescript가 생성하는 AST는 ESLint가 생성하는 AST와 다르다. 따라서 Typescript의 AST는 오랜시간동안 eslint 사용자들이 작성한 수많은 rule과 맞지 않는 다는 것을 의미한다.

하지만 ESLint는 여러 플러그인을 붙여서 lint configuration을 할 수 있도록 해놓았다. parser도 마찬가지로 javascript를 사용할때는 espree라는 기본 parser를 사용하면 되지만 typescript의 경우에는 @typescript-eslint/parser를 따로 설치 및 설정 해 두어야 한다.

이와같이 ESLint 라는 기본 틀에 typescript 관련 플러그인을 추가 구성하는 방식으로 typescript를 지원하고 있으므로 @typescript-eslint/eslint-plugin, @typescript-eslint/parser등을 각각 설치 해 주어야 하는 것이다.


ESLint + Typescript + vscode 환경을 세팅해보자!

  1. ESLint 관련 package를 설치한다.

    1
    yarn add -D eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-plugin-react standard
  2. .eslintrc.yaml에 eslint 관련 초기 세팅 및 rule 세팅을 해준다.

  3. vscode에 eslint 확장자를 설치한다.

  4. vscode settings에서 Format on save 검색하여 켜준다.

  5. Format이 적용되지 않은 파일에서 save를 해보자

    • Before
    • After

ESLint sharable config 생성 및 배포 🚀

우리는 프로젝트를 생성할 때 마다 eslint를 적용하기 위해 수많은 패키지를 설치 한다 ㅠㅠ.. 이 과정을 한번에 할수는 없을까?

eslint는 관련 세팅을 패키지화 해서 npm에 upload 할 수 있다. 이것을 sharable config라고 하며 만약 현재의 lint 설정 과정을 패키지화 해놓는다면, 프로젝트를 만들 때 마다 같은일을 반복하지 않을 수 있어 개발 효율을 높일 수 있다.

Publish to npm

  1. 프로젝트 이름을 eslint-config-[설정 이름] 으로 세팅한다.

    • eslint-config-wonjerry 폴더 생성
    • yarn init을 통해 package.json을 생성한다.
  2. package.json에서 peerDependency에 eslint config가 사용하는 peer dependency를 명시 해 준다.

  3. Index.js에 원하는 eslint rule 들을 설정해준다.

  4. yarn publish 명령어를 통해 publish 한다.
    version, npm username, npm email, npm password 등을 입력하고 publish 한다. (당연히 npm 회원 가입은 되어있어야겠죠?)

Install in project

  1. eslint-config를 사용할 프로젝트에서는 npm을 통해 해당 config를 install 한다.

    1
    yarn add -D eslint-config-wonjerry
  2. eslintrc.yaml 파일을 생성하고 eslint-config-wonjerry를 extends 한다고 적어준다.

  3. eslint . —ext .ts —ext .tsx && tsc 명령어로 확인해서 잘나오면 성공!! 만약 lint 관련 error가 뜬다면 잘 수정해주면 된다.

    1
    2
    $ eslint . --ext .ts --ext .tsx && tsc
    ✨ Done in 3.71s.

Conclusion 🛬

이렇게 eslint를 편하게 쓰기 위해 eslint sharable config를 만드는 것 까지 완료하였다. eslint sharable config를 잘 설정해 둔다면 개인 프로젝트 또는 회사의 프로젝트에서 편하게 lint setting을 할 수 있어 개발 효율을 높였다.

댓글

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×