본 포스트는Angular - Architecture overview 의 내용을 개인적인 메모의 목적으로 재게재 한 것입니다.
아키텍처 개요
Angular는 HTML과 타입스크립트(TypeScript)를 이용하여 웹브라우저에서 동작하는 응용 프로그램(클라이언트)을 개발하기위한 플랫폼이자, 프레임워크입니다. Angular는 타입스크립트로 작성되어 있습니다. 타입스크립트 라이브러리를 이용하여 Angular 앱에서 필수적으로 사용해야하는 코어(Core) 부분과 Angular 앱에서 선택적으로 사용할 수 있는 기능들을 구현하였습니다.
_NgModule_은 Angular 앱의 기본 구성 요소로 내부에 포함되어 있는 컴포넌트(components) 들에 대한 컴필레이션 컨텍스트(compilation context)1를 제공합니다. 다시말해 NgModule 은 기능적으로 관련있는 코드의 집합이고, Angular 앱은 이러한 NgModule 들을 모아 작성합니다. Angular 앱은 최소한 부트스트랩을 위한 루트모듈(root module) 을 포함하고 있으며, 일반적으로는 여기에 _기능 모듈(feature modules)_을 추가하여 작성합니다.
-
컴포넌트는 NgModule의 구성요소로 뷰(views) 를 정의합니다. 뷰는 Angular 앱의 로직과 데이터를 Angular가 선택하고 변경할 목적으로 화면에 표시되는 요소들 입니다. 쉽게 말해 사용자가 눈으로 볼 수 있는 모든 것을 의미합니다. 모든 Angular 앱은 루트 컴포넌트를 가지고 있습니다.
-
서비스(Service) 는 뷰에 직접적으로 관계하지 않는 기능을 제공할 목적으로 다른 컴포넌트들이사용하는 컴포넌트 입니다. 서비스 제공자(Service Provider)는 의존성(Dependency) 으로 컴포넌트에 주입(Injection) 할 수 있습니다. 이 방식을 통해, Angular 에서는 코드를 모듈화하여 재사용을 효율적으로 할 수 있습니다.
컴포넌트와 서비스는 모두 간단한 타입스크립트 클래스입니다. 여기에 그 클래스의 유형과 Angular에게 이 클래스를 어떻게 사용하면 될 지 알려주는 메타데이터를 제공하는 데코레이터(decorator) 가 추가된 것일 뿐입니다.
-
컴포넌트 클래스의 메타데이터는 뷰를 정의하는 템플릿(Template) 과 해당 컴포넌트 클래스를 연결합니다. 템플릿은 일반적인 HTML과 Angular 지시자(directives) 와 바인딩 마크업(binding markup) 을 조합하여 작성합니다. Angular는 템플릿을 웹브라우저 화면에 렌더링(표시)하기 전에 미리 일반 HTML으로 변환합니다.
-
서비스 클래스의 메타 데이터는 Dependency Injection (DI) 를 통해 다른 컴포넌트에서 해당 서비스를 사용할 수 있도록 정보를 제공합니다.
앱에 포함되어 있는 컴포넌트들은 일반적으로 다수의 뷰를 정의합니다. Angular는 이들 뷰 사이의 탐색 경로를 정의하기 위해 Router서비스를 제공합니다. 라우터 서비스는 브라우저에서의(in-browser) 탐색 기능을 제공합니다.
모듈
Angular에서는 JavaScript (ES2015) 모듈을 보완한 NgModule을 정의합니다. NgModule 에는 응용 프로그램 도메인, 워크 플로우, 또는 일련의 기능과 밀접하게 관련된 컴포넌트들의 컴파일 컨텍스트를 선언합니다. NgModule 은 내부에 포함된 그 컴포넌트들을 서비스 등의 관련 코드와 묶어, 기능단위로 구성합니다.
모든 Angular 응용 프로그램은 일반적으로 AppModule
라는 루트 모듈 (root module) 이 Angular 앱을 시작하는 부트스트랩 메커니즘을 제공합니다. 일반적인 Angular 앱에는 이외에도 많은 기능 모듈이 포함되어 있습니다.
JavaScript의 모듈과 마찬가지로 NgModule 은 다른 NgModule에서 필요한 기능을 가져오고, 자신의 기능을 다른 NgModule이 사용할 수 있게 내보낼 수 있습니다. 예를 들어 앱에서 라우터의 서비스를 사용하려면 Router의 NgModule를 가져옵니다.
코드를 기능모듈로 조직하면 복잡한 응용 프로그램의 개발과 재사용의 설계를 관리하는데 도움이 됩니다. 또한 이 기법을 사용하면 지연로드(lazy-loading) - 즉 요구에 따라 모듈을 로드 - 를 사용할 수도 있는데, 이를 통해 Angular 앱이 시작할 때 로드해야하는 코드의 양을 최소화할 수 있습니다.
모듈에 대한 더 자세한 내용은 모듈 개요 를 참조하십시오.
컴포넌트(Component)
모든 Angular 앱에는 루트 컴포넌트를 포함해 적어도 하나 이상의 컴포넌트가 있습니다. 루트 컴포넌트(root component) 는 컴포넌트의 계층구조를 페이지의 DOM에 연결합니다. 각 컴포넌트는 Angular 앱의 데이터와 로직을 포함하는 클래스를 정의하고 대상 환경에서 표시할 뷰를 정의하는 HTML 템플릿(Template) 에 연결됩니다.
@Component 데코레이터는 바로 아래의 클래스를 컴포넌트로 인식하며, 템플릿 및 관련 컴포넌트별 메타 데이터를 제공합니다.
데코레이터는 JavaScript 클래스를 변경하는 함수입니다. Angular는 특정 유형의 메타 데이터를 클래스에 추가하는 데코레이터들을 정의하고 있기 때문에, 그 클래스의 의미와 동작을 알 수 있습니다.
템플릿, 지시자 및 데이터 바인딩
템플릿은 HTML과 HTML 요소를 랜더링(표시)하기 전에 수정할 수 있는 Angular 마크업을 조합하여 구성합니다. 템플릿 지시자(directives) 는 프로그램 로직을 제공하고 바인딩 마크업(binding markup) 는 앱의 데이터(e.g. 클래스 멤버변수 등)와 문서객체모델(DOM)을 연결합니다.
- 이벤트 바인딩(event binding) 을 사용하면 Angular 앱이 데이터를 업데이트하여 대상 환경의 사용자 입력에 응답 할 수 있습니다.
- 속성 바인딩(property binding) 을 사용하면 앱의 데이터에서 계산된 값을 HTML 요소로 변환할 수 있습니다.
뷰가 표시되기 전에 Angular는 지시자를 평가고, 템플릿 바인딩 구문을 결정하여 앱의 데이터와 논리에 따라 HTML 요소와 DOM으로 변환합니다. Angular는 양방향 데이터 바인딩 을 지원합니다. 즉, 사용자의 선택 등 DOM 변경을 앱의 데이터에 반영시킬 수 있습니다.
템플릿에서는 파이프(pipe) 를 사용하여 값의 표기방식을 변환하여 사용자 경험을 향상시킬 수 있습니다. 예를 들어, 날짜 및 통화값을 사용자의 지구상의 위치에 따라 적절한 방법으로 표시하기 위해 파이프를 사용합니다. Angular는 일반적인 변환에 대해 미리 정의된 파이프를 제공합니다. 또한, 개발자가 신규로 파이프를 정의 할 수 있습니다.
이러한 개념에 대한 자세한 내용은 컴포넌트의 개요 를 참조하십시오.
서비스(Service)와 의존성 주입(Dependency Injection)
특정뷰에 관련되지 않으며 컴포넌트간에 공유할 수 있는 데이터 또는 로직의 경우 여러분은 이를 서비스(service) 클래스로 만들면 됩니다. 서비스 클래스의 정의 앞에는 @Injectable 데코레이터가 있습니다. 이 데코레이터는 의존적으로 클라이언트 컴포넌트에 서비스를 주입(injection) 하기위한 메타 데이터를 제공합니다.
Dependency Injection (또는 DI)을 사용하면 컴포넌트 클래스를 효율적으로 유지할 수 있습니다. 컴포넌트가 서버에서 데이터를 검색하거나 사용자의 입력을 확인하거나 콘솔에 직접 로그를 작성할 수는 없습니다. 그런 작업은 서비스에 위임합니다.
자세한 내용은 서비스와 DI 소개 를 참조하십시오.
라우팅
Angular의 Router NgModule 은 Angular 앱의 다양한 상태와 뷰 계층 사이에서 탐색 경로를 정의할 수 있는 서비스를 제공합니다. 이것은 여러분에게 친숙한 브라우저 탐색 규약을 따르고 있습니다.
- 주소 표시줄에 URL을 입력하면 브라우저가 해당 페이지로 이동합니다.
- 페이지의 링크를 클릭하면 브라우저에서 새 페이지로 이동합니다.
- 브라우저 전/후의 버튼을 클릭하면 브라우저는 여러분이 본 페이지의 내용을 앞뒤로 이동합니다.
라우터는 URL과 같은 경로를 페이지 대신 뷰에 매핑합니다. 링크 클릭과 같은 사용자가 새 브라우저에서 페이지를 로드하는 작업을 수행하면 라우터는 브라우저의 작동에 개입하고 뷰 계층을 표시하거나 숨깁니다.
만약 현재의 응용 프로그램 상태에 특정 기능이 필요하며, 그것을 정의하는 모듈이 로드되지 않았다면, 라우터는 필요에 따라 해당모듈을 지연로드 할 수 있습니다.
라우터는 앱의 뷰 탐색 규칙 및 데이터의 상태에 따라 링크 URL을 해석합니다. 사용자가 버튼을 클릭하거나 드롭 박스에서 선택하거나 또는 임의의 소스에서 다른 자극에 반응할 때 새 뷰로 이동할 수 있습니다. 라우터는 브라우저 기록에 활동을 기록하기 때문에 뒤로 및 앞으로 버튼도 작동합니다.
탐색 규칙을 정의하려면 탐색 경로(navigation path) 를 여러분의 컴포넌트에 연결하면 됩니다. 탐색 경로는 프로그램 데이터를 템플릿과 통합하는 하는 것과 동일한 방식으로 URL 유사 구문을 사용하여 여러분의 뷰를 프로그램 데이터와 통합합니다. 이후, 여러분은 프로그램의 논리를 적용하여 사용자의 입력과 자체 액세스 규칙에 따라 어떤 뷰를 표시하거나 숨길 것인지를 선택할 수 있습니다.
자세한 내용은 라우팅 및 탐색 을 참조하십시오.
결론
Angular 앱의 주요 구성 요소에 대한 기초를 배웠습니다. 다음 그림은 이러한 기본 구성요소들이 어떻게 관련되어 있는지를 보여줍니다.
- 컴포넌트와 템플릿은 Angular 뷰를 정의합니다.
- 컴포넌트 클래스의 데코레이터는 관련 템플릿의 참조를 포함한 메타 데이터를 추가합니다.
- 컴포넌트의 템플릿에서 지시자와 바인딩 태그는 프로그램 데이터와 논리에 따라 뷰를 변경합니다.
- 의존성 주입은 뷰 사이의 탐색을 정의 할 수 있는 라우터 서비스 등의 서비스를 컴포넌트에 제공합니다.
이장에서 간략히 소개한 각 내용은 다음 페이지에서 자세히 설명합니다.
TypeScript가 파싱과 분석을 올바르게 할 수 있도록 관련된 파일을 묶는 것을 멋지게 표현한 것에 지나지 않습니다. ↩︎
'모듈, 프레임웍 > Angular' 카테고리의 다른 글
Angular Material 설치 및 간단한 예시 (0) | 2018.09.08 |
---|---|
컴필레이션 컨텍스트 (Compilation context) (0) | 2018.08.01 |
Angular 시작하기 (0) | 2018.06.13 |
Angular 개발환경 설정하기 (0) | 2018.06.13 |
Angular 살펴보기 (0) | 2018.06.10 |