타입스크립트 6일차 - 모듈

모듈의 필요성

제가 지금 다니는 회사 말고 전에 회사를 다녔을 때 만줄이 넘는 페이지를 본 적이 있었습니다.

언어는 ASP였고 레거시 시스템을 가지고 유지보수를 했는데 전에 만들었던 사람이 함수를 한군데 다 짱박아 놓는 바람에 nodepad가 버벅거릴정도로 라인수가 많은 페이지를 열었던 엄청난 경험이었습니다.

찾기를 해도 한참돌다가 찾아지는 그 오묘함이란 말도 못할 경험이었죠.

그래서 필요한 부분만 따로 떼서 유지보수와 작업을 수월하도록 만드는 모듈화가 필요한 것입니다.

타입스크립트에서는 세 가지의 이점을 누릴 수 있습니다.

유지보수의 용이성

쉽게 말하면 만줄짜리 열고 버벅거리는것을 느끼면서 찾을래? 백줄짜리 열고 빠르게 찾을래? 이 뜻인것 같습니다.

애초에 요즘 모듈화 안하면 욕먹기 딱좋죠..

전역 스코프 오염을 방지

JS namespace에 변수이름이나 함수이름을 중복해 선언할 수 없는 규정이 있는데 내가 이 이름을 쓰고싶은데 못쓰는 경우를 방지하기 위해서 입니다.

특히 JS의 전역 공간(global namespace)를 침범하지 않게 되므로 중요합니다.

재사용성 향상

모듈화를 잘 해놓으면 현재 프로젝트 뿐 아니라 다른 프로젝트에서도 가져다 쓸 수 있습니다.

저는 JAVA의 문자열 유틸을 가지고 다른분들이 미리 만들어 놓은 모듈을 가져다 잘 쓰고 있습니다.

내부모듈과 외부모듈

타입스크립트에서는 내부모듈과 외부모듈로 구분하게 됩니다.

버전 1.5가 등장하면서 네임스페이스라는 특징과 ES2015 모듈의 특징이 추가 되었고 ECMA스크립트 표준 용어집에 따라 두 가지로 나뉘게 되었습니다.

이 두가지의 모듈은 내부모듈과 외부모듈로 나뉘게 되었는데 각각에 대해서 보겠습니다.

내부모듈

네임스페이스라고 불리는 단위의 이름 공간입니다.

따라서 같은 네임스페이스의 공간이라면 별도의 참조문 없이 참조할 수 있는데 파일이 다르더라도 네임스페이스가 같다면 이름을 중복할 수 없습니다.

물론 네임스페이스가 다르다면 문제 없습니다.

네임스페이스는 전역 스코프에 속하지만 전역 스코프와는 독립된 공간이라는 점이 특징입니다. 그래서 라이브러리 단위의 모듈을 구성할 때 사용하면 좋습니다.

네임스페이스란?

하나의 독립된 이름 공간을 만들고 여러 파일에 걸쳐 선언된 이름 공간을 공유하도록 만들 수 있는 방식입니다.

선언할 때 module이라고도 부르지만 표준인 namespace로 더 많이 부릅니다.

사용법은 다음과 같습니다.

1
2
3
4
5
namespace a {
function b(){
//TODO...
}
}

이러한 네임스페이스의 선언명만 같다면 hello1.ts도 hello2.ts도 같은 네임스페이스를 사용할 수 있습니다.

예를 들면, 인터페이스와 이를 구현한 클래스를 분리해서 각각 파일로 만든다고 쳤을 때 한번에 폴더를 전부 컴파일하면 문제는 없습니다.
그런데 클래스만 컴파일 하게 된다면 인터페이스를 찾을 수 없기 때문에 문제가 발생합니다.
그래서 타입스크립트에서는 명시적으로도 네임스페이스가 같지만 물리적으로는 다른 파일을 참조할 수 있게 문법을 제공합니다.

/// <reference path="파일경로">의 문법을 사용하여 참조하면 됩니다.

네임스페이스의 이름 확장

네임스페이스에서는 예외로 .을 하용합니다.

점(.)을 사용하면 네임스페이스간의 계층을 만들 수 있습니다.

1
2
3
namespace Animal{...}
namespace Animal.Pet{...}
namespace Animal.Pet.dog{...}

이런식으로 상위부터 하위로 차례대로 선언해주시면 됩니다.

물론 한파일내라면 어떻게든 참조는 가능하기에 문제는 없습니다만 논리적으로 저렇게 쓰도록 추천하고 있습니다.

외부모듈

export로 주로 선언되는 모듈을 외부모듈이라 합니다. 대부분의 모듈이라 하면 외부모듈을 말하는 것이죠.

export를 쓸 수 있는 대상은 변수, 함수, 클래스, 네임스페이스까지 가능하며 공간이 파일 내부로 제한되는 특징이 있습니다.

즉, export로 선언하지 않아서 외부 모듈이 되지 않으면 전역스코프의 공간을 공유하기 때문에 이름 충돌이 발생합니다.

타입스크립트의 경우는 표준인 ES2015외 CommonJS, AMD 등 여러가지 형식도 같이 지원하고 있습니다.

모듈선언과 import

타입스크립트에서 추가된 ES2015의 모듈시스템은 export나 import를 통해 모듈을 선언하고 호출합니다.

간단한 사용법은 다음과 같습니다.

1
2
3
4
5
6
7
//1개짜리일경우
export '노출하고자 싶은 모듈의 이름'
import 불러올 모듈명 from '파일경로'

//여러개를 노출하고 싶은경우
export {'모듈명1', '모듈명2', ...}
import {'불러올 모듈명1', '불러올 모듈명2', ...} from '파일경로'

만약 함수나 인터페이스 단위를 개별적으로 노출하려면 export interface ...이나 export function ...식으로 가능하며 ES6로 컴파일하면 해당 선언문은 그대로 유지됩니다.

이상으로 간단하게 모듈에 대한 설명을 마치겠습니다.