[Angular] Angular Modules(NgModule)
본 아티클에서는 Angular 2.4.4 버전에서 테스트 되었습니다.
Angular 응용프로그램은 컴포넌트와 디렉티브, 파이프, 서비스 등의 조합으로 이루어진다.
응용프로그램의 규모가 커질 수록, 이러한 구성요소들을 특정 기준에 따라 그룹화시켜 관리하는 것이 좋은데 이를 위해 Angular에서는 @NgModule이라는 decorator를 통해 모듈화 구성을 지원한다.
Angular의 모듈 구성을 사용하면, 컴포넌트들을 논리적으로 그룹핑하여 관리할 수 있으며
라우팅과 연계하면 모듈 단위 Lazy Loading을 구현할 수도 있다.
(참고: 논리적 그룹이라는 측면에서 보면 닷넷의 namespace, 자바의 package와 유사할 것이다.)
Angular의 모듈화 구성에 대해 살펴보자
@NgModule Decorator
Angular 모듈구성을 위한 메타데이터 객체정보를 전달받는 데코레이터 함수이다.
전달된 메타데이터 정보에 기반해서 현재 모듈로 구성해야할 컴포넌트와 디렉티브, 파이브 등의 정보를 식별하고 외부로 노출할 컴포넌트를 결정한다.
전달되는 메타데이터 속성은 다음과 같다.
1) declarations
- 현재 모듈에 포함시킬 뷰 클래스들을 지정.(뷰 클래스 종류: 컴포넌트/디렉티브/파이프)
2) exports
- declarations에서 정의한 현재 모듈의 구성요소를 다른 모듈의 템플릿에서 사용할 수 있도록 노출시킬 뷰 클래스들을 지정.(여기서 지정하지 않은 뷰 클래스들은 다른 모듈에서 사용 불가)
3) imports
- 다른 모듈에서 노출(exports)한 뷰 클래스들를 사용하기 위해 해당 모듈 임포트.
4) providers
- 공통 서비스의 등록. 등록된 서비스는 앱의 모든 부분에서 사용 가능.
5) bootstrap
- 메인 뷰로 사용될 루트 컴포넌트 지정. 루트모듈에서만 지정가능.
(https://angular.io/docs/ts/latest/guide/architecture.html#!#modules 참고)
이제 @NgModule을 사용해서 모듈화 구성의 초간단 샘플을 작성해보자.
두 가지 형태로 테스트를 해볼텐데, 첫번째는 규모가 작은 응용프로그램이라는 가정 하에 단일 모듈(루트모듈) 구성을 두번째는 서브모듈을 하나 더 만들어 볼 것이다.
1. 루트 모듈만 사용
Angular는 최소한 하나 이상의 모듈로 구성해야 하는데, 가장 기본이 되는 모듈이 바로,
루트모듈(Root Module)이다. angular-cli로 프로젝트를 생성하면 루트모듈이 자동으로 생성된다.
기본 생성된 구조에서, 컴포넌트와 서비스를 추가해보자.
추가된 컴포넌트는 sub.component와 sub.service이다. 폴더구조와 소스는 다음과 같다.
* 폴더구조
* 소스(sub.service.ts)
* 소스(sub.component.ts)
새로 추가한 SubComponent는 서비스를 주입 받아서 id/name 데이터를 획득해서 자신의 멤버변수에 할당하는 간단한 코드이다.
이렇게 추가한 SubComponent를 루트 컴포넌트에 해당하는 AppComponent에서 사용하기 위해 AppComponent의 HTML에 SubComponent 태그를 추가시킨다.
* 소스(app.component.html)
그런데 이렇게 사용하려면 루트 모듈에 SubComponent와 SubService에 대한 참조가 정의되어 있어야 한다.
* 소스(app.module.ts)
이로써 결과를 확인할 수 있게 되었다.
* 결과화면
2. 모듈 분리하기.
앞서 루트모듈만 사용했을 경우 문제는, 프로그램 규모가 복잡하고 커질 경우 상당량이 컴포넌트/서비스/파이프/디렉티브가 생기게 되는데 이것들을 모두 하나의 모듈로 관리해야 하기 때문에 구조가 비직관적으로 복잡해지고 모듈단위 관리(라우팅 및 비동기모듈로딩 등)가 용이하지 않다는 점이다.
이에 데모를 조금 변경하여 모듈을 분리해 보자.
SubComponent와 SubService를 묶어서, 별도의 다른 모듈로 그룹화 시키기 위해 SubModule을 생성한다.
* 소스(sub.module.ts)
여기서 주의 할 점은 이 모듈의 컴포넌트를 외부 모듈에서도 사용하게끔 하려면 exports로 명시를 해줘야 한다는 것이다.
이렇게 함으로써 Sub집합(여기서는 하나의 컴포넌트와 하나의 서비스)을 별도의 Angular 모듈로 만들었으며 이 모듈을 루트모듈에서 사용하려면 다음과 루트모듈을 수정하면 된다.
* 소스(app.module.ts)
앞서 루트모듈만 사용했을 때에는, 컴포넌트와 서비스를 모두 참조해야 했지만 모듈을 분리하고 나서는 해당 모듈(여기서는 SubModule)만 참조하면 된다.
그리고 결과화면은 (볼 것도 없이) 앞의 예와 동일한다.
다음 아티클에서는 모듈과 연관되는 라우팅(Routing)에 대해 정리할 예정.
* 참고자료
- Angular 공식 가이드
- Angular Architecture Overview
- Angular Tutorial