본문 바로가기

Dev.Project/Todolist_project

[TodoMVC] Step 1. 각 JS 파일 모듈화하고 의존성 관계 확립하기

Step 1. 각 JS 파일 모듈화하고 의존성 관계 확립하기

첫번째 단계. 코드를 작성할 모듈들을 준비하고,

각각의 관계와 역할을 정리해두자.


우선, app.js 파일을 작성한다.

app.js code>

1
2
3
4
5
6
7
8
9
10
11
12
(function(){
    'use strict';
    function App(){
        console.log('App created!');
        this.storage = new app.Storage(name);
        this.model = new app.Model(this.storage);
        this.template = new app.Template();
        this.view = new app.View(this.template);
        this.controller = new app.Controller(this.model, this.view);
    }
    var todo = new App();
})();
cs


모듈화를 시키기 위해 즉시 실행 함수로 app.js에 작성될 코드를 감싸준다.

그리고 'use strict' 키워드를 통해, 문법적인 문제가 없는지 확인한다.

App 이라는 생성자 함수를 통해, 각종 생성자 함수를 생성하고 모듈간 의존성 관계를 확립할 것이다.

위 코드를 통해 각각의 모듈들이 다음과 같은 구조를 취하고 있다는 것을 알 수 있다.

cf) storage에 인자로 전달되는 name은 localstorage에서 key 값으로 사용되므로 아무 값이나 넣어주면 된다.


architecture >



이제 각각의 js 파일들을 모듈화 시키자.

초기 단계이므로 모든 파일의 구조가 거의 비슷다.

생성자 함수를 정의하고, 모듈을 exports 변수를 통해, 외부로 노출시킨다.

노출시킬 때도, app 이라는 namespace안에 노출시킨다.


template.js code>

1
2
3
4
5
6
7
8
(function(exports){
    'use strict';
    function Template(){
        console.log('template created');
    }
    exports.app = exports.app || {};
    exports.app.Template = Template;
})(this);
cs


Template 파일은 생성자 함수에 html 코드 조각을 담고 있을 것이다.

View가 Rendering 할 때 넘겨받는 data 인자로 html 코드 조각의 일부를 치환하여,

우리가 원하는 형식으로 입력한 데이터를 출력하는 일종의 템플릿 엔진 역할을 수행하게 된다. 



view.js code>

1
2
3
4
5
6
7
8
9
10
(function(exports){
    'use strict';
    function View(template){
        console.log('view created!');
        this.template = template;
    }
    exports.app = exports.app || {};
    exports.app.View = View;
})(this);
 
cs


뷰는 화면에 데이터를 그리는 ( 뿌리는 ) 역할을 수행한다. ( 가장 복잡한 구조를 갖추게될 view이다...)

Template 을 인자로 받아 자신의 프로퍼티에 추가하였다.

View에서는 생성자 함수에 조작해야 할 Element를 저장해둘 것이다.

그리고 Controller와 binding 되어, 레코드의 변경을 바로바로 화면에 렌더링하는 역할을 할 것이다.

이번 프로젝트에서는 Controller 에 이벤트를 등록하지 않고 View에서 이벤트를 등록할 것이다.

화면을 구성하고 있는 요소는 View에서 접근할 수 있어야 MVC의 역할 구분이 명확해지기 때문이다.

 


controller.js code>

1
2
3
4
5
6
7
8
9
10
(function(exports){
    'use strict';
    function Controller(model, view){
        console.log('controller created!');
        this.model = model;
        this.view = view;
    }
    exports.app = exports.app || {};
    exports.app.Controller = Controller;
})(this);
cs


컨트롤러의 역할은 모델과 뷰를 연결하는 것이다.

모델과 뷰에 모두 접근해야하므로, 두 가지를 인자로 넘겨받아, 자신의 프로퍼티에 추가하였다.

모든 바인딩이 컨트롤러에서 이루어지며, 사용자의 요청을 받는 부분이 컨트롤러이다.



model.js code>

1
2
3
4
5
6
7
8
9
10
(function(exports){
    'use strict';
    function Model(storage){
        console.log('Model created!');
        this.storage = storage;
    }
    exports.app = exports.app || {};
    exports.app.Model = Model;
})(this);
 
cs


모델은 데이터와 직접적으로 관련된 역할을 수행한다.

Storage와 Communication 하기 위해 storage를 인자로 넘겨받아, 자신의 프로퍼티에 추가하였다.

데이터를 create, read, update, delete 하는 역할을 수행하게 된다.


storage.js code>

1
2
3
4
5
6
7
8
9
(function(exports){
    'use strict';
    function Storage(){
        console.log('store created!');
    }
    exports.app = exports.app || {};
    exports.app.Storage = Storage;
})(this);
 
cs


일종의 데이터베이스와 같은 역할을 수행한다. ( 데이터와 직접적인 연산을 한다. )

이번 프로젝트에서는 LocalStorage를 사용하여 데이터를 저장하고 읽어올 것이다.

Model에서 불리는 Callback 함수에 의해 데이터를 출력하고 입력받는다.




위에서 언급했듯이, 모든 모듈들을 app이라는 Namespace에 저장해두었다.

전역 공간을 최대한 깨끗하게 사용하기 위함이다.


일부러 모든 생성자 함수 안에 console.log( )를 남겨놨다.

각 모듈들이 제대로 로드되는지, 생성자 함수들에 의해서 new가 제대로 되는지 확인해보길 바란다.

크롬 개발자 도구를 열고 (MAC : option + command + I ) console 창을 들여다보자.


이 개발자 도구는 항상 옆에 열어두고 하는 것이 좋다!

물론 http-server npm을 실행시킨 터미널도 가끔 봐주면 좋다.

경로를 못찾거나 제대로 로드되지 않았을 때, 붉은 글씨로 알려준다.


참고로 index.html 에서 script 태그로 각 js 파일을 로딩할 때, app.js 파일이 제일 밑으로 와야한다!

한 가지 더 덧붙이자면, 자바스크립트는 오타에 매우 취약하다. 눈을 크게 떠야한다! ( 물론 크게 떠도, 잘 안보인다. )




Step 1. The End


>> Step 2. To do list Add Item / list 추가하기>>