모바일/Javascript

[AngularJS] Module

박종명 2016. 7. 12. 13:57
728x90

AngularJS의 Module(모듈)은 평범한 HTML 페이지를 AngularJS 응용프로그램으로 확장시키기 위한 진입점이다. AngularJS는 Module을 통해 controller, service, filter, directive 등을 추가하는 방식으로 동작한다.

또한 전역네임스페이스를 오염시키지 않는 전형적인 모듈패턴을 지향하며 나아가 모듈화 프로그래밍을 가능케 하는 아키텍처링 방법으로 설계되었다.

AngularJS 모듈을 그 역할 관점에서 다음과 같이 다양하게 정의해 볼 수 있을 것이다.

- HTML 페이지를 AngularJS 응용프로그램으로 확장시키기 위한 진입점

- HTML 페이지와 AngularJS가 상호작용하기 위한 매개체

- 연관된 각종 컴포넌트를 포함하는 컨테이너

- AngularJS 응용프로그램의 구성을 논리적으로 조직화하는 단위

- 모듈화 프로그래밍을 지원하는 AngularJS의 아키텍처 지원 기능

 
* Module 생성과 로딩
- 모듈 생성과 로딩은 모두 angular.module 함수를 통해 이뤄진다. 첫 번째 매개변수는 모듈 이름을 지정하며 두 번째 매개변수는 해당 모듈과 연관된 서브모듈을 배열으로 지정할 수 있다.
서비모듈 지정은 모듈을 생성할 때만 지정 가능하다.

//모듈 생성
angular.module("myApp", []);

//생성한 모듈 가져오기
var app = angular.module("myApp");


* HTML페이지를 AngularJS 앱으로 확장시키기
- 이렇게 생성한 모듈을 HTML 페이지의 특정 Element에 지정하면 그 Element하위 요소들은 AngularJS 응용프로그램으로 동작가능하게 된다. 이때 ng-app 지시자를 통해 해당 앱이 사용할 모듈이름을 지정한다. (참고로 한 페이지에 모듈은 하나만 지정이 가능한데 만일, 두 개 이상의 서로다른 모듈을 지정한 경우 HTML 페이지 기준으로 가장 상단에 지정된 모듈만이 정상 동작할 것이다.)

<script>
 var app = angular.module("myApp", []);
</script>
<div ng-app="myApp">...</div>

 

* 모듈에 컴포넌트 추가하기
- 모듈은 연관된 각종 컴포넌트를 포함하는 컨테이너 역할을 하며, 이렇게 필요에 의해 추가된 컴포넌트들을 이용하여 HTML페이지를 동적인 MVC 어플리케이션으로 동작시킬 수 있다.

다음 그림은 모듈을 통해 구성가능한 컴포넌트를 보여준다

(출처: http://www.c-sharpcorner.com/article/module-and-controller-in-angularjs/)

실제로 AngularJS 학습의 대부분은 그림에서 보는 것과 같은 컴포넌트의 사용법을 익히는 것이다. 각 컴포넌트의 상세한 설명은 개별 주제를 다룰 때 보기로 하고 여기서는 대략 다음과 같은 코드로 모듈에 필요한 컴포넌트를 추가할 수 있다는 것만 알고 넘어가자

var app = angular.module("myApp", []);   //모듈 생성

app.controller("MyCtrl", function() { } ); //모듈에 컨트롤러 정의

app.service("MySvc", function() { } ); //모듈에 서비스 정의

app.directive("MyDir", function() { } ); //모듈에 디렉티브 정의

패턴은 거의 동일하다. 각 컴포넌트에 해당하는 메서드를 호출하고 컴포넌트의 이름과 익명함수를 전달하는 방식으로 동작한다. 모듈 메서드는 다음 그림을 참고하기 바란다.

참고) 모듈의 로딩(설정블럭과 실행블럭)
- AngularJS의 모듈 로딩은 설정단계와 실행단계라는 두 단계를 거치며 각 단계를 위한 코딩블럭이 제공된다.

(설정블럭, Configuration blocks)
- 모듈 로딩의 첫 단계로, 모든 프로바이더를 연결하고 등록한다. 오직 프로바이더와 상수만이 설정블록에 주입될 수 있다.

(실행블럭, Run blocks)
- Injector가 생성된 후에 실행되며, 응용프로그램을 시동하는데 사용된다. 이 시점 이후에 추가적인 시스템 설정이 이뤄지는 것을 방지하기 위해, 실행블록에는 오직 인스턴스와 상수만을 주입할 수 있다.
 

AngularJS는 응용프로그램을 실행할 때, 해당 모듈의 설정영역을 먼저 실행한 후 실행영역을 실행시킨다. 실행영역은 일종의 main 메소드 같은 역할로 모든 서비스가 설정되고 인젝터가 생성된 후에 실행된다.

설정블럭과 실행블럭에 대한 자세한 내용은 다음 블로그를 참고하기 바란다.
- AngularJS의 설정단계(configuration phase)와 실행단계(run phase)


* 모듈화 프로그래밍(서브 모듈 사용하기)
- AngularJS의 Module은 응용프로그램의 구성을 논리적으로 조직화하는 단위로써도 역할을 한다. 아마 이것이 AngularJS Module의 핵심가치일 것이다.
이로써 모듈화 프로그래밍이 가능해 지는 것인데, 모듈화를 하면 연관된 것끼리는 묶고 서로 다른 것끼리는 분리해서 조직화 가능하며 필요한 모듈을 그때그때 조합해서 하나의 전체 응용프로그램을 완성시킬 수 있다. 이 역시 '관심사의 분리'라는 대원칙이 적용된 SW설계 기법이며 모듈화가 잘 이뤄진 프로그램은 재사용성/생산성/유지보수성이 향상되고 테스트용이성도 높아진다.
(공학적으로 모듈화가 잘 되었다는 것은 '응집도'는 높고 하게 '결합도'는 낮게 구성하는 것이다)

모듈화의 가치는 응용프로그램의 규모에 따라 달라진다.
아주 작고 간단한 프로그램 환경에서는 모듈화가 복잡성만 증가시키는 별 필요없는 기법이 된다.
하지만 프로그램의 크기가 상당하고 여러명의 개발자가 참여하는 개발환경이라면 모듈화는 거의 필수적인 기법이라 할 수 있다.

 간단한 시나리오를 가정해 보면, ToDo 리스트를 관리하는 앱을 개발할 경우 다음과 같이 조직화 가능할 것이다.
- 메인모듈, 공용모듈, 사용자모듈, 인증모듈, ToDo 아이템 모듈, ....

순전히 개인적인 구분이지만, 프로그램의 성격과 규모에 따라 모듈화의 기준은 달라질 것이다.

다음 코드예제는 AngularJS Module을 이용해 모듈을 역할별로 분리하고 이를 조합하여 구성한 즉 모듈화 프로그램을 작성한 예이다.

먼저 MyApp이라는 메인 모듈을 생성하고 이 모듈이 의존하는 서브모듈(MyApp.User, MyApp.Common)을 배열로 전달한다.
MyApp.User 모듈은 사용자정보를 추상화한 모듈이며, MyApp.Common 모듈은 전체 응용프로그램에 공통적으로 사용될 상수를 정의한 모듈이다. 이 각각의 모듈은 메인모듈의 서브모듈로 등록되어 메인모듈의 컨트롤러의 생성자 함수에 서브모듈의 컴포넌트가 주입되는 방식으로 동작한다.

<!DOCTYPE html>
<html>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>

<script>
var myApp = angular.module("MyApp", ["MyApp.User", "MyApp.Common"]);
myApp .controller("MainCtrl", function(userlist, APPLICATION_CONFIG){
 var main = this;
 main.users = userlist.getUsers();
 main.appConfig = APPLICATION_CONFIG;
});

var userModule = angular.module("MyApp.User", []);
userModule.service('userlist', function(){ 
   var user = this;
   var mock = [
       {name: 'Park', city: 'Pusan'},
       {name: 'KIM', city: 'Seoul'},      
     ];    
   user.getUsers = function(){
     return mock;
   };
})

var commonModule = angular.module("MyApp.Common", []);
commonModule.constant("APPLICATION_CONFIG", {config1: "value1", config2: "value2"});

</script>

<body>
<div ng-app="MyApp" ng-controller="MainCtrl as main">
<h1>Users</h1>
  <ul>
     <li ng-repeat="user in main.users">
        {{user.name + ', ' + user.city}}
     </li>
   </ul>
   <div>{{ main.appConfig.config1 + ", " + main.appConfig.config2 }}</div>
</div>
</body>
</html>

 

* AngularJS 내장 모듈과 3rd-Party 모듈
- 앞서 모듈화 코드에서 구현한 모듈은 일종의 사용자 정의 모듈이다. 즉 개발자가 필요에 의해 임의로 생성한 모듈이다.
AngularJS는 유용한 기능을 미리 모듈화 시켜두고 이를 사용할 수 있도록 하고 있다. 이것을 AngularJS 내장모듈이라고 하는데 대표적으로 다음과 같은 것들이 있다.
- ngRoute: URL 라우팅 기능 제공
- ngAnimate: 애니메이션 기능 제공
- ngCookies: 웹 쿠키 기능 제공

더 많은 내장 모듈이 있지만, 차차 알아보기로 한다.

또한 인터넷의 제 3자에 의해 유용한 기능들을 모듈화하여 제공하기도 한다. 마치 플러그인 처럼 필요한 모듈을 가져다가 자신의 응용프로그램에 적용할 수 있다.

다음 사이트는 AngularJS 모듈을 검색하거나 새로운 모듈을 등록할 수 있다.
- http://ngmodules.org/

 

 * 참고자료
- https://docs.angularjs.org/guide/module
- http://www.w3schools.com/angular/angular_modules.asp