TypeScript는 coffee.js와 같은 자바스크립트 precompiler(전처리기)이다.
이 프로그램은 일종의 중간 언어로 작성된 코드를 전처리기가 처리하여,
시중의 자바스크립트 엔진이 활용할 수 있는 코드를 생성하는 목적으로 사용한다. TypeScript의 경우 javascript와 유사한 중간 언어를 학습해야 한다는 단점이 있지만,
이름 그대로 type을 명확히 따지므로 형 불일치 문제를 피할 수 있으며,
자바스크립트만의 ‘자바스크립트 패턴’을 사용하지 않아도 된다는 장점이 있다.
왜 ‘자바스크립트 패턴’을 사용해야 하는가?
물론 가장 큰 목적은 ‘유지보수 가능한 프로그램의 작성’에 있다.
그러나, 자바스크립트에는 다른 언어에 당연히 존재할법한 기능들이 생략되어 있는 경우가 대부분이라,
자바스크립트로 대규모 프로그램을 작성할 경우에는 이것이 큰 장애물이 되기 때문이다.
예를 들어, 이 ‘자바스크립트 패턴’을 활용해서 ECMA5문법으로 클래스를 만든다고 했을 때..
개발자는 여러가지 제약사항을 극복해야만 한다.
블록 단위 스코프를 지원하지 않는다.
캡술화를 지원하지 않는다.
프로토타입을 사용하여 상속을 구현해야만 한다.
기타 등등..
이를 타계하고자 전 세계의 천재들이 머리를 쥐어 짜 만든 결과물이 ‘자바스크립트 패턴’인 것이다.
예를 들어 코드의 재활용성을 극대화하기 위해 상속 메커니즘을 사용해야 한다면
다음과 같은 일종의 무공비급(?)을 활용해야 한다.
2015년 6월에 확정된 ECMA6에도 상속 문법은 정의되어 있지만
대부분의 자바스크립트 엔진들이 이를 지원하지 않는다는 문제점이 있다.
재미있게도 TypeScript는 ECMA6와 매우 유사한 문법을 지원하는데,
coffeeScript같은 기타 프리컴파일러와 비교했을 때 가장 큰 장점이라고 할 수 있다.
다음의 파일을 exmple.ts로 저장한 후.
이렇게 프리컴파일 명령을 내리면
다음처럼 ECMA5문법으로 작성된 js를 자동으로 생성해 준다.
단, 이만큼 난해한 코드가 생성되었으니 유지보수에는 타입스크립트를 반드시 사용해야 할 것이다.
개인적으로는 Typescript의 문법이 ECMA6 문법과 비슷하다는 것을 통해,
미래의 자바스크립트 명세를 주도하려는 MS의 고도의 전략을 읽을 수 있었다.
사람들이 Typescript를 쓰면 쓸 수록 미래 자바스크립트 명세에 대한 MS의 지분이 커질 것 아니겠는가?
그만큼 브라우저 기술을 주도할 여지가 생기는 것이고..
그러나 Typescript를 정작 실무에 도입하려면 단점이 있는데..
역사 깊고 친숙한 라이브러리들과 함께 사용하려면, 해당 라이브러리의 명세서.
즉 일종의 헤더 파일이 필요하다는 것이다.
그것이 확장자 .d를 가지는 Definition파일인데 반드시 이를 사용해야만 Typescript의 장점을 활용할 수 있다.
즉 TypeScript로 jQuery나 node.js를 사용하려면 헤더파일이 필요하다는 단점이 있다.
물론 그런 것을 라이브러리 제작자들이 만들어 줄 이유 따위는 없으므로..
해당 라이브러리의 내부를 모두 파악해서 수작업으로 만들어 내야 하는데.
이미 다른 사람들이 부지런하게 매니저까지 만들어서 활용하고 있다.. 가져다 사용하기만 하면 되겠다..
저 많은 라이브러리들을 분석해서 해더 파일로 만들어낸 전 세계의 수많은 개발자에게 잠시 경의를 표한다..
Definition파일이 약 930여개 모여 있다. 그것도 오직 TypeScript를 위해!!
잠시 저 definition file 매니저의 사용법을 해설하자면.
다음과 같이 매니저를 설치하고
그 후, 루트 디렉토리에서 다음 커맨드를 입력하면 node.js의 definition file이 다운로드 된다.
그리고 ts파일에 임포트. 헤더 파일을 로드하는 과정과 비슷하다.
이 시점에서 나는 깨달았다… Definition파일 때문에 다수가 작업하는 프로젝트의 경우에는 다른 팀원들에게 반드시 TypeScript를 교육시켜야 한다는 문제를… 그러나 나에게 그 자존심 강하고 실력 좋은 사람들을 설득시킬 에너지와 명분 따위가 있을 리 없다…
그래서 Typescript에 대한 나의 탐구는 여기에서 멈추었다. byebye..
angular2.0이 Typescript로 작성된다는 사실이 마음에 걸리긴 했지만.. 현실적인 제약이 너무 컸다.
그래서 Babel로 눈을 돌려 보았더니 새로운 세계가 펼쳐져 있었는데..
Typescript같은 경우에는 Definition파일의 존재는 차치하고라도, 일단 ECMA6문법과 유사한 Typescript만의 문법을 사용해야 한다는 제약이 있지만..
Babel은 ECMA6를 ECMA5로 변환시켜주는 진정한 트랜스파일러였던 것이다.
자바스크립트의 멍청한 문법 때문에 파이썬에 보다 집중하고 었었는데..
자바스크립트를 파이썬과 비슷하게 사용할 수 있다면. 이건 더 이상 망설일 이유가 없다.
Babel은 ECMA5를 ECMA6로 바꾸어 준다는 큰 장점 이외에도 자바스크립트 모듈을 매우 쉽게 만들 수 있다는 장점이 있다.
그러나 실무에 모듈화를 도입하려면 amd방식 모듈을 만들지, commonJs방식 모듈을 만들지의 여부를 선택해야 하는 문제가 있다.
서버에서 사용하려면 commonJs방식을, 클라이언트에서 사용하려면 require.js로 대표되는 amd 방식을 선택하는 것이 일반적이나,
자세히 알아보고 싶으신 분은 아래의 포스트를 확인하시길.
그렇다면 앞서 살펴본 Typescript는 amd 혹은 commonjs를 지원하는 모듈을 만들어 줄까?
Parent 클래스와 Child클래스를 익스포트 해 보면..
이를 다음 명령을 통해 TypeScript가 지원하는 모듈로 만들면..
Typescript 또한 모듈 문법을 지원하지만, 결과물은 단순한 IIFE에 불과하다는 치명적인 단점이 있었다.
저 IIFE는 서버, 클라이언트 어느 환경에서도 파일 단위 모듈을 구현하기엔 부적합하다.
그러나 Babel은 ECMA6문법으로 작성된 모듈을 commonjs, amd등의 방법으로 변환할 수 있도록 지원한다.
이를 다음 명령을 통해 node.js에서 주로 사용하는 commonJs 모듈로 만들면..
그리고 다음 명령을 통해 클라이언트의 require.js에서 주로 사용하는 amd 모듈로 만들면..
Typescript는 독자 문법을 사용하고도 IIFE를 만들어 내는데, Babel은 공식적인 ECMA6문법을 사용함에도 commonjs, amd모듈을 만들어 내는 것이다.
(물론 기계가 작성한 코드이기에 장황하긴 하지만..)
이것이야말로 일석 삼조.
Bable을 사용하면 ECMA6를 지원하는 자바스크립트 엔진은 물론이고, ECMA5용 브라우저, ECMA5용 서버에서 모두 사용할수 있는 모듈을 생산하는 수단이 생기는 것이다.
그러나 이는 단지 이상일 뿐, 위 코드에 명시된 의존성 모듈을 통해서 알 수 있듯, babel은 ecam6의 상당수 스펙을 polyfill로 구현하고 있다. 문제는 이 polyfill이 commonjs로 작성되어 있기에 amd모듈이 commonjs방식의 polyfill모듈을 로드하지 못하는 사태가 발생한다.
결국 commonjs방식의 모듈만 사용해야 하는 것이나 마찬가지이다.
여기서 결론.
TypeScript의 장점
ECMA6와 비슷한 중간 언어로 ECMA5용 코드를 생성할 수 있다.
프리컴파일시에 Type을 엄격하게 검사하므로, Type을 검사하는 코드를 적을 필요가 없어진다.
TypeScript의 단점
TypeScript를 새로 학습해야만 한다.
TypeScript를 다른 팀원들에게 학습시켜야만 한다.
만들어 내는 모듈이 IIFE에 불과하다.
Babel의 장점
ECMA6 코드로 ECMA5용 코드를 생성할 수 있으므로 자바스크립트 엔진이 업그레이드 되더라도 대처할 수 있다.
ECMA6 코드로 amd용, commonJs용 모듈과 그를 사용하는 코드를 생성해 낼 수 있다.
ECMA6 코드로 ECMA6에 정의된 새로운 기능을 마음껏 사용할 수 있다.
Babel의 단점
ECMA6에 새로 정의된 기능 중 상당수가 polyfill로 구현되어 있는데, 모든 polyfill들이 commonJs방식을 따르기에 amd모듈의 생성은 가능하지만, 실제로는 commonJs모듈만 사용해야 한다.