typescript와 eslint,prettier 를 적용한 NodeJS 백엔드 개발 환경 구축하기
사실 js 개발할때 기본중의 기본이지만 이때까지 이렇게 해본적이 없다.
그래서 이번기회에 정리하고 적용하려고 한다.
시작하기 전에 내가 typescript-eslint 환경을 설정하면서 겪었던 문제들을 써보자면 tsconfing.json
과 eslint
의 기본룰 그리고 @typescript-eslint
플러그인의 세 가지의 규칙들이 서로 겹치면서 어떤 규칙은 적용되고 어떤규칙은 적용이 안돼는 여러문제들이 발생했었다. 그래서 3 가지를 모두 사용하면서 필요에따라 tsconfing의 규칙을 켜거나 eslint의 규칙을 끄는등 세세한 규칙들을 조정해서 적용했다. 내가 인터넷에서 참고한 자료들도 포스트 마다 설정과 규칙들도 제각각이라 헷갈리는 내용도 많았다. 다만 확실한건 lint를 쓴다는건 코딩 스타일을 개선하고 버그를 줄이기 위함이지 무조건 따라야 하는 규칙이 있는건 아니라는것이다. 이 포스트의 내용도 정답이 아닐수 있으니(물론 틀렸을수도 있으니) 참고 바란다.
먼저 필요한 패키지들을 설치한다.
이 패키지들은 개발환경에서만 필요하기때문에 -D 옵션을 써주자.
npm i -D typescript eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin
typescript와 eslint는 설명할필요도 없고 각각의 @typescript-eslint/parser
와 @typescript-eslint/eslint-plugin
패키지는 typescript용 eslint 규칙을 적용하기위해 필요한 플러그인들이다.
npm i -D eslint-config-airbnb-base eslint-plugin-import
그리고 eslint-config-airbnb-base
패키지를 설치한다.
eslint-config-airbnb-base 패키지는 javascript의 ES6 문법과 typescript의 eslint 규칙을 모아놓은 일종의 탬플릿이라고 생각하면 된다.
eslint의 규칙도 여러사람들이 작성한 규칙들이 많아데 그 중 많이 쓰이는 규칙중 하나이다.
eslint-plugin-import
는 airbnb 규칙을 사용할때 필요로하는 패키지이다.
npm info "eslint-config-airbnb-base@latest" peerDependencies
이 명령어를 실행하면 eslint-config-airbnb-base 라는 패키지에서 필요로 하는 패키지 목록을 확인할수 있다.
prettier
란 코드포맷터로써 정해진 규칙대로(여기선 eslint 에 맞게) 에디터에 작성한 코드를 자동으로 수정해주는 플러그인이다.
예를들면 몇칸 만큼 띄어쓰기를 해야하는지, 코드 끝부분에 세미콜론을 붙이는지의 여부등 설정을 해주면 그에 맞게 코드가 자동으로 수정된다.
이 prettier를 사용하기 전에 먼저 짚고 넘어가야할 내용을 알아보자.
먼저 prettier와 linter의 차이점을 알아보자. prettier 공식 문서에도 linter 와 비교하는 글이 있는데 간략히 설명하자면 linter는 서식 규칙(Formatting rules)
과 코드 품질 규칙(Code-quality rules)
을 준수한다. 서식 규칙이란 공백을 얼마나 넣어야할지,코드 한줄의 최대 길이는 몇인지,콤마는 어디다 넣어야하는지 등 말그대로 코드를 보기좋게 하기위한 규칙 들이며 코드 품질 규칙 규칙이란 쓰지않는 변수 제거, 함수 코드 작성 규칙 등 코드의 품질을 높이기 위한 규칙들이다. 하지만 둘을 비교할때 prettier는 코드 서식만 보완하는게 목적이지 코드 품질 까지 관리하지는 않는다고 한다.
우리의 목적은 이 prettier와 linter를 같이 사용하는것인데 아쉽게도 둘을 같이 사용하면 충돌이 일어날 가능성이 있다고 한다. 그래서 공식 문서에서는 prettier와 linter를 같이 사용하기 위한 방법을 설명하고있다. 이 방법은 eslint에서 불필요하거나 prettier와 충돌할수있는 모든 규칙을 꺼버리고 prettier에게 eslint의 코드 품질 규칙을 넘겨줘서 마치 prettier가 eslint처럼 동작하게 만드는 방법이다. 주의사항으로 eslint의 모든 서식관련 규칙이 꺼져있어야만 제대로 작동을하고 그렇지 않다면 오류가 발생한다고 말한다.
아무튼 prettier와 eslint를 같이 사용하기 위해 필요한 아래의 패키지도 설치해준다.
npm i -D prettier eslint-config-prettier eslint-plugin-prettier
npx tsc -init
이 명령어를 실행하면 tsconfig.json 파일이 생성된다. 코딩 스타일은 사람마다 전부 다르니 옵션을 읽어보고 필요한대로 설정해서 쓰자.
vscode의 마켓플레이스에서 eslint와 prettier 플러그인을 설치한다.
프로젝트의 루트 디렉토리에 각각 .prettierrc
와 .eslintrc.js
파일을 생성한다.
//.prettierrc
//json 파일에서는 주석이 허용되지 않으니 지워주자
{
"singleQuote": true, //문자열을 감쌀때는 ['] 사용
"parser": "typescript", //사용할 구문 파서
"semi": true, //코드 끝에 자동으로 세미콜론 붙이기
"useTabs": false, //공백 대신 tab으로 들여쓰기
"tabWidth": 2, //들여쓰기 공백의 길이
"printWidth": 120, //코드 한줄의 최대 길이
"arrowParens": "always" //화살표함수 작성시 항상 괄호 생성
}
더 자세한 내용은 prettier 옵션 문서를 확인해보자.
//eslintrc.js
module.exports = {
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint', 'import'],
extends: [
'airbnb-base',
'plugin:@typescript-eslint/recommended',
'plugin:prettier/recommended',
'plugin:import/errors',
'plugin:import/warnings',
],
rules: {
'prettier/prettier': 0,
'@typescript-eslint/no-unused-vars': 'error',
},
settings: {
'import/resolver': {
node: {
extensions: ['.js', '.ts'],
},
},
},
};
옵션의 내용들을 알아보자.
parser - eslint 가 코드를 파싱할때 사용할 파서이다. typescript를 파싱하기 위해 @typescript-eslint/parser를 사용한다.
plugins - 플러그인이란 eslint의 구성과 규칙,env 등이 포함된 npm 모듈을 가져와서 쓸수있다. typescript eslint 규칙이 포함된 @typescript-eslint/eslint-plugin 패키지를 로드한다는 뜻이다.
extends - eslint의 규칙을 확장할때 쓰인다. 여기서 쓰인 airbnb-base 란 플러그인 구성에 추가적인 airbnb-base 라는 구성을 확장하겠다는 뜻이다. recommended 란 해당 패키지에서 권장하는 규칙들을 사용한다는 뜻이다.
rules - 위에서 적용한 규칙들을 커스터마이징 하거나 추가 규칙을 설정할수있다. 주로 규칙을 오버라이딩 할때 사용한다. 여기서는 @typescript-eslint 패키지의 no-unused-vars 란 옵션을 error 로 판단하게끔 규칙을 수정하였다.
이제 실제 코드 에디터에서 eslint가 적용되었는지 확인하자.
제대로 설정이 완료되었다면 에디터에서 규칙에 어긋나는 코드가 있다면 알려준다.
몇주전 직장동료 한테서 내가 개발하는 방식에 대해서 지적을 받은적이 있다.
바로 개발을 하면서 npm script를 사용하지 않고 그냥 node app.js 같이 node로 바로 코드를 실행시키는거에 대한 내용이었는데 사실 이때까지 개발을 할때는 실행만 되면 그만이라 생각하고 nodejs를 처음 배웠을때부터 지금까지 습관처럼 이렇게 해왔는데 직장동료가 내가 개발하는 스타일을 보고는 왜 이런 기본적인걸 활용을 안하지? 하고 의문이 들었다는 말을듣고 충격에 빠졌었다.
잘못된 습관의 무서움을 다시한번 깨닫고 지금이라도 활용하는 방법을 익혀보기로 했다.
자세한 설명과 사용 방법은 여기에 정리되어있으니 참조하자.
나같은 경우는 개발할때와 실제 배포를할때 env나 몇가지 설정이 달라질때가 많아 개발할때 쓰이는 dev
스크립트와 배포할때 쓰는 prod
스크립트를 따로 작성해 보았다.
//package.json의 script 부분
"scripts": {
"dev": "cross-env NODE_ENV=development ts-node ./src/app.ts",
"prod": "cross-env NODE_ENV=product (빌드 or deploy 스크립트)",
},
스크립트에 맨앞에 쓴 cross-env 란 windows 환경에서 node 명령어를 실행할때 환경변수를 쓸수있게 해주는 라이브러리이다. 보통 개발환경과 배포환경을 구분하기 위해 코드를 실행할때 NODE_ENV
라는 환경변수로 구분을 하는데 dev 스크립트일경우 이 값을 development 로 지정하고 배포환경 일때는 product 와 같이 지정해서 코드를 실행할때 서로 다르게 동작하도록 구분한다.
그리고 소스코드 상에서 NODE_ENV 값에 따라서 개발용 env 파일을 사용할지 배포용 env 파일을 사용할지 여부를 결정한다.
//app.ts
import dotenv from 'dotenv'
dotenv.config({
path: process.env.NODE_ENV === 'development' ? '개발용 env 경로' : '배포용 env 경로'
})