Please enable JavaScript to view the comments powered by Disqus.

VSCode와 Babel Flow 플러그인으로 타입을 헐렁하게 써보자

2018-08-11 · 읽기 5

자바스크립트와 정적 타입

자바스크립트는 타입을 명시적으로 지정하지 않는 동적 타입 언어다. 하지만 프론트엔드 앱의 복잡도가 높아지고 서버에서도 자바스크립트가 사용되면서 자바스크립트에 정적 타입을 적용하는 사람들이 많이 늘어났다. 현재 TypeScript(이하 ‘타입스크립트’)는 2018년 8월 현재 주간 다운로드 수 200만이 넘고 있으며 Flow(이하 ‘플로우’)를 사용하기 위한 Babel 플러그인도 100만회 이상 다운로드 되고 있다.

앱의 규모가 커지면서 수많은 함수와 컴포넌트를 작성하다 보면 이 함수가 어떤 형태의 객체를 반환하는지, 컴포넌트가 어떤 값을 전달받아야 하는지 전부 기억하기 어렵다. 코드를 통한 유추, API 문서, 디버깅과 로그를 통해 확인하는 과정을 모두 생략하게 해주는 것이 타입이다. 그 외에도 많은 역할을 하는 타입 정의는 내게 보고 있는 것이 무엇인지 알려주는 친절한 파트너가 될 수 있다.

하지만 개인적으로는 여전히 타입 없이 프로그래밍하는 쪽을 더 선호하는 편이다. 이유는? 역시 손이 많이 가기 때문이다. 손이 많이 간다는 건 작업 시간이 늘어난다는 말과 같다. 물론 시간을 들인 만큼 소프트웨어가 더 견고해질 수 있다. 즉 오류에 강해진다. 하지만 오류가 줄어든다고 해서 소프트웨어와 코드의 품질이 무조건 좋아지는 것은 아니며, 타입 검사기로는 찾을 수 없는 오류는 여전히 발생할 수 있다.

하지만 복잡한 구조의 객체를 타입을 선언하고 함수의 리턴값을 정의해서 에디터에서 즉시 참조할 수 있도록 하는 건 역시 멋진 일이다. 타입이 필요 없는 곳도 많지만, 있으면 좋은 곳도 많다. 그런 부분에서 타입을 사용해서 답답함을 해결해주는 자동완성(intellisense), 이 기능만큼은 너무 매력적이다. 하지만 타입 검사를 본격적으로 도입하는 건 너무 깐깐한 선생님에게 밀착 지도를 받는 것 같아서 별로 그러고 싶지 않다. 타입을 선언하지 않으면서 개발한 코드를 타입스크립트나 플로우로 옮기면 빨간 줄과 노란 줄이 엄청나게 뜬다. 타입스크립트는 아예 컴파일 오류를 내서 앱이 실행되지 못하게 해버리고, 플로우는 실행은 되지만 시선을 분산시켜서 개발에 도대체 집중할 수 없게 만든다.

고통받는 개발자 에디터와 개발자의 관계 역전

내가 필요한 곳에만 타입을 붙이면서 검사는 받지 않는 것. 관심 있는 부분만 공부하면서 커닝 노트를 만들지만 정작 시험은 보고 싶지 않은 마음이랄까? 그게 무슨 어중간하고 불량한 태도냐고 할 수도 있지만 뭐 어떠랴. 개발 방법론에 왕도가 있는 것도 아니고.

느슨하고 편하게 타입을 사용하기 위한 도구

이런 방식으로 타입을 사용하려면 기본적으로 컴파일 과정이 필요한 타입스크립트는 사용할 수 없다. 하지만 자바스크립트에서 타입을 선언하면 콜론(:)이 찍힌 위치에서 ‘Unexpected token :’ 같은 메시지와 함께 오류가 발생한다. 이를 막기 위해서는 소스 코드에서 타입을 제거하는 도구가 필요한데, 플로우 타입 시스템을 사용하기 위한 Babel 플러그인이 그 역할을 한다.

타입 주석(annotation)을 제거하는 Babel 플러그인

Babelbabel-plugin-transform-flow-strip-types 플러그인을 사용하면 소스 변환(transpile) 과정에서 타입 주석을 모두 제거한다. 만약 Babel을 사용하고 있지 않다면 다른 도구가 있으니 그것을 사용하면 된다.

타입 검사기 역할을 하는 VSCode

그리고 VSCode처럼 자동완성을 잘 지원하는 텍스트 에디터를 조합하면 좋다. 2018년도에 개발자들에게 인기도 1위를 차지한 마이크로소프트의 VSCode는 주요 대상이 웹과 클라우드 기반 프로그래밍이며 타입스크립트와 함께 성장한 에디터(하지만 이제는 확장 기능 추가를 통해 IDE에 버금가는 수준으로 구성할 수 있다. 물론, 그만큼 느려진다)인 만큼 DOM과 자바스크립트 기본 객체에 대한 자동완성을 무척 잘 지원한다.

documentElement 자동완성

타입스크립트의 사용자가 크게 늘어나면서 많은 라이브러리에 타입 정의 파일(*.d.ts)이 작성되어 있는 상황이다. VSCode에서는 자바스크립트 소스 파일에서도 모듈에 타입 정의 파일이 있으면 자동완성을 지원한다.

npm 모듈 자동완성

특히 VSCode는 타입스크립트가 아닌 자바스크립트 파일에서도 타입 정의 파일을 사용해서 자동완성을 지원한다. 코드에서 유추가 가능하다면 사용자가 정의한 객체에 대해서도 자동완성을 지원한다.

vscode가 유추한 state 객체의 타입

컴포넌트의 state 객체에는 별도로 타입을 지정하지 않았지만, 기본값으로 공백 문자를 지정한 것을 바탕으로 string 타입이라고 안내한다. 같은 컨텍스트 내부에서 이 정도의 자동완성은 타입 선언 없이 가능하다. 하지만 실제로 앱을 개발하다 보면 에디터가 도움을 주지 못하는 상황이 훨씬 더 많다. 예를 들어 함수 내부에서 XHR을 사용해서 Promise 객체가 반환될 때, 실제로 어떤 값이 resolve 되는지 자바스크립트에 안에서 어떻게 표현할 것인가? 타입 정의를 사용하면 가능하다.

vscode의 Promise

Promise를 돌려주는 getData 함수에 타입을 정의해서 Data 타입이 resolve 된다고 표현해 두었다. 그러면 VSCode는 콜백 함수에서 타입에 기반을 둔 자동완성을 제공한다.

플로우 타입 주석을 제거하는 도구를 사용하면서 타입스크립트 문법을 사용할 수 있는 이유는 둘 다 type, interface 키워드, union, generic, intersection 타입 등을 지원하기 때문이다. 하지만 한계는 당연히 존재한다. 플로우의 유틸리티 타입인 $Keys, $Values 같은 타입은 VSCode가 해석하지 못하며, 타입스크립트에만 있는 keyof 같은 키워드를 사용하면 트랜스파일 과정에서 오류가 발생한다. 하지만 공통으로 지원하는 문법만 사용해도 충분히 쓸만하다.

사용하기에 편하지만, 단점은?

이 방식을 사용하면 변수의 타입을 확인할 수 있고 자동완성도 사용할 수 있다. 하지만 플로우나 타입스크립트가 제대로 된 타입을 사용하고 있는지 체크는 하지 않기 때문에 코드에서 잘못된 값을 사용해도 아무런 알림을 주지 않는다.

타입 체크는 당연히 안한다 빨간 줄 없이 깨~끗

이 방식을 사용하면 잘못된 타입을 선언해 붙여두거나, 변경된 타입을 그대로 내버려둬서 생기는 문제는 모두 사용자가 책임져야 한다. 자유가 늘어나면 책임도 늘어난다는 일반적인 명제가 여기에 적용되는 셈이다.

하지만 타입을 편하게, 부담감 없이 사용하고 사람에게는 권해보고 싶다. 플러그인 하나만 추가하면 되고 설정도 필요 없다. 그리고 모든 장소가 아닌 ‘필요한 곳에만’ 꼼꼼함을 발휘하면 된다.