[angular]검색결과, 3건
지난 주, 이틀에 걸쳐 사내강의를 진행했다.
주제는 'Angular4로 SPA 개발하기'로 Angular 개발에 관한 강의였다.
대체로 현업에서 관련 기술이 요구되는 개발자 분들이 참여했으며, 나역시 많은 것을 배울 수 있는 기회였다.
사내강사(SSAM) 뱃지
교육과정
교육교재
강의시작
데모 소스
본 아티클에서는 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
'모바일 > Javascript' 카테고리의 다른 글
Proxy to Back-end(프론트엔드단 CORS 통신설정) (13) | 2017.07.28 |
---|---|
Javascript Compiler, Babel (10) | 2017.03.16 |
Isomorphic Javascript (8) | 2017.01.23 |
[Node] npm(node package manager) (10) | 2017.01.20 |
[Angular] Lazy Loading (14) | 2017.01.18 |
앞서 'SPA의 단점에 대한 단상'이라는 글에서 초기 구동속도 문제에 대해 다루었었다.
SPA의 초기 구동속도 문제를 완화하기 위해, 모듈을 청크단위로 분리해서 해당 모듈이 필요한 시점이 되었을 때 관련 리소스들이 다운로드 될 수 있도록 하는 Lazy Loading 기법을 사용할 수 있다.
Angular2에서는 모듈 단위로 컴포넌트와 서비스, 파이프 등 각종 구성요소들을 논리적으로 그룹화 시키고 해당 모듈단위로 Lazy Loading을 적용할 수 있는데, 이의 구현에 대해 알아본다.
1. 시나리오는 대략 이렇다
1) 총 3개의 모듈(일반적인 웹 페이지 개념으로는 3개의 웹 페이지라고 생각하자)
2) 첫 구동 페이지(메인페이지에 해당)에서는 메인 구성을 위한 리소스만 다운로드
3) 나머지 두 개의 페이지도 그 페이지에 요청이 있을 경우에만 관련 리소스 다운로드
4) 이후에는 모든 페이지를 재 방문해도, 새로고침 없이 다운로드 된 리소스 사용
2. Angular 개발 환경은 다음과 같다.
참고로 부트스트랩 3.3.7도 사용.
3. 데모 프로젝트 디렉터리 구조는 다음과 같다.
앞서 시나리오와 같이 총 3개의 페이지를 위한 3개의 Angular 모듈 구성(one/two/three)
4. 각 모듈의 라우팅 구성은 다음과 같다.
1) 루트 라우팅 구성
2) 하위 모듈 라우팅 구성
5. 각 모듈 구성은 다음과 같다.
1) 루트 모듈
2) 하위 모듈 구성
컴포넌트 구성은 중요한 것이 아니라서, 생략하고 프로젝트를 빌드 한다
6. 청크(Chunk)단위 모듈 로딩 확인하기
1) 메인 페이지 요청
Angular 구동을 위한 번들 파일과 메인페이지의 리소스들을 다운로드 받는다.
2) 두번째 페이지 요청
두번째 페이지에서 사용하는 모듈이 번들링된 청크파일과 리소스만 로딩
3) 세번째 페이지 요청
세번째 페이지에서 사용하는 모듈이 번들링된 청크파일과 리소스만 로딩
이제 모든 리소스가 다운로드 되었고, 이후부터는 해당 페이지들을 다시 방문해도 (비동기 통신 데이터를 제외하고는) 이미 다운로드 된 리소스들을 사용해서 반응성이 빨라지게 된다.
추가로 이 데모에서는 초기 페이지의 컴포넌트 재생성을 방지하기 위해 사용자 정의 RouteReuseStrategy를 적용해서 매번 컴포넌트 생성을 하지 않게끔(싱글톤) 하였다.
아래 이미지를 확인해 보면, 세 개의 페이지를 왔다갔다 할 때 첫번째 페이지의 컴포넌트의 경우 더 이상 객체를 생성하지 않는 것을 알 수 있다.(해당 로그는 객체의 생성자에서 기록하도록 했음)
'모바일 > Javascript' 카테고리의 다른 글
Isomorphic Javascript (8) | 2017.01.23 |
---|---|
[Node] npm(node package manager) (10) | 2017.01.20 |
SPA 단점에 대한 단상 (9) | 2017.01.17 |
[Webpack] 비동기 번들 로딩 (8) | 2017.01.14 |
[Webpack] 자바스크립 모듈 번들러, 웹팩(Webpack) (8) | 2017.01.12 |