블로그 이미지
윤영식
Full Stacker, Application Architecter, KnowHow Dispenser and Bike Rider

Publication

Category

Recent Post

2014. 1. 29. 07:48 AngularJS/Start MEAN Stack

Git, Node.js, Yeoman등 기본적인 개발환경을 설치하였다면 소프트웨어 요구사항 정의서 (Software Requirements Specification, SRS) 에서 정의한 화면을 CSS Framework을 사용하여 만들어 보자. 여기서는 가장 많이 사용하고 있는 Twitter Bootstrap을 사용토록 한다. 



사전준비

  이전 글에서 yeoman의 yo 명령을 통하여 angular 프로젝트를 "meanstack"이름으로 생성하였다. meanstack 하위에 app 폴더가 앵귤러 기반의 SPA (Single Page Application) 프론트앤드 애플리케이션의 ROOT 폴더가 된다. 


  - 반응형 웹 디자인 기반의 메뉴구조를 구성한다 

  - 메뉴를 클릭하면 해당하는 html 파일로 라우팅한다 

  - 메뉴에 아이콘을 추가한다 




1. Twitter Bootstrap 설치

 Twitter Bootstrap은 meanstack을 생성하면서 app/index.html에 자동 추가된다. 

  1) <!-- build:css ... --> : 주석은 제거하면 안된다. grunt build 시에 css 압축할 때 사용하는 주석이다. (build:js 도 동일) 

  2) <!-- bower:css .. --> : 주석은 제거하면 안된다. grunt build 시에 자동으로 bower install 한 내역을 추가한다. (bower:css 도 동일) 

// index.html

    <!-- build:css styles/vendor.css -->

    <!-- bower:css -->

    <link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.css" />

    <!-- endbower -->

    <!-- endbuild -->


   .. 중략 ..


    <!-- build:js scripts/vendor.js -->

    <!-- bower:js -->

    <script src="bower_components/jquery/jquery.js"></script>

    <script src="bower_components/angular/angular.js"></script>

    <script src="bower_components/bootstrap/dist/js/bootstrap.js"></script>

    <script src="bower_components/angular-resource/angular-resource.js"></script>

    <script src="bower_components/angular-cookies/angular-cookies.js"></script>

    <script src="bower_components/angular-sanitize/angular-sanitize.js"></script>

    <script src="bower_components/angular-route/angular-route.js"></script>

    <!-- endbower -->

    <!-- endbuild -->

  * "yo angular meanstack" 명령으로 twitter bootstrap이 자동 설치가 되면 twitter bootstrap이 사용하는 fonts 폴더를 app/fonts로 자동 복사해 준다. 이것은 grunt build시에 모든 css가 app/styles/*.css로 압축되고 bootstrap의 css가 사용하는 font는 ../fonts를 참조하기 때문이다. 따라서 배포를 위해서는 app/fonts 폴더가 존재 해야한다.




2. Angular UI-Bootstrap 설치

  Twitter Bootstrap을 html에 적용하려면 class 정보를 입력해야 한다. 이를 좀 더 직관적인 html tag 형식으로 쓸 수 있도록 AngularUI 팀에서 Directives를 만들었다. 예로 tab을 적용하가 위하여 <tab> 태그를 html에 사용하면 angular-bootstrap 모듈이 <tab> 를 class="tab" 형태로 바꿔서 DOM에 적용하는 것이다. html을 좀 더 직관적으로 작성할 수 있다는 장점이 있다. 

$ bower install angular-bootstrap --save

angular-bootstrap#0.10.0 app/bower_components/angular-bootstrap

└── angular#1.2.10


  bower를 통해 angular-bootstrap을 설치 후 "grunt build" 또는 "grunt serve" 를 실행하면 index.html에 필요 파일이 자동 추가된다. 자동 추가되는 파일의 정보는 bower_components/angular-bootstrap/bower.json 파일에 지정되어 있다.

// index.html 파일 

   <!-- build:js scripts/vendor.js -->

    <!-- bower:js -->

    <script src="bower_components/jquery/jquery.js"></script>

    <script src="bower_components/angular/angular.js"></script>

    <script src="bower_components/bootstrap/dist/js/bootstrap.js"></script>

    <script src="bower_components/angular-resource/angular-resource.js"></script>

    <script src="bower_components/angular-cookies/angular-cookies.js"></script>

    <script src="bower_components/angular-sanitize/angular-sanitize.js"></script>

    <script src="bower_components/angular-route/angular-route.js"></script>

    <script src="bower_components/angular-bootstrap/ui-bootstrap-tpls.js"></script>

    <!-- endbower -->

    <!-- endbuild -->


  angular-bootstrap은 별도의 앵귤러 모듈이므로 애플리케이션에서 사용하려면 모듈 의존성을 설정해야 한다. meanstack 서비스의 메인 소스는 app/scripts/app.js 이다. 여기에 모듈 의존성을 설정한다. 

  - 형식 : angular.module('<ApplicationName>', [<의존성 모듈 열거>]);

// app/bower_components/angular-bootstrap/ui-bootstrap-tpl.js 파일 상단

angular.module("ui.bootstrap", ["ui.bootstrap.tpls", "ui.bootstrap.transition","ui.bootstrap.collapse","ui.bootstrap.accordion","ui.bootstrap.alert","ui.bootstrap.bindHtml","ui.bootstrap.buttons","ui.bootstrap.carousel","ui.bootstrap.position","ui.bootstrap.datepicker","ui.bootstrap.dropdownToggle","ui.bootstrap.modal","ui.bootstrap.pagination","ui.bootstrap.tooltip","ui.bootstrap.popover","ui.bootstrap.progressbar","ui.bootstrap.rating","ui.bootstrap.tabs","ui.bootstrap.timepicker","ui.bootstrap.typeahead"]);



// app/scripts/app.js 안에 추가 

'use strict';

angular.module('meanstackApp', [

  'ngCookies',

  'ngResource',

  'ngSanitize',

  'ngRoute',

  'ui.bootstrap'

])

  .config(function ($routeProvider) {

    .. 중략 ..

  });



3. Angular UI-Router 설치 

클라이언트 화면 전환을 위한 라우팅 기능은 앵귤러에서 제공하는 기본적인 라우터를 사용하지 않고 AngularUI팀에서 역시 제공하는 ui-router (https://github.com/angular-ui/ui-router)를 사용한다. ui-router는 한 화면에서 멀티 view 설정으로 원하는 부분들의 DOM을 변경처리할 수 있다. bower를 통해 ui-router v0.2.7 버전을 설치한다. ui-router v0.2.8 버전설치에 오류가 존재하기 때문이다. 또한 설치전에 Angular.js 버전을 현재 (2014.1.28기준) 최신버전인 v1.2.10 으로 업데이트한다.

// bower.json 파일에서 angular 관련 버전을 1.2.10 으로 지정한다 

$ vi bower.json

{

  "name": "meanstack",

  "version": "0.0.0",

  "dependencies": {

    "angular": "1.2.10",

    "json3": "~3.2.6",

    "es5-shim": "~2.1.0",

    "jquery": "~1.10.2",

    "bootstrap": "~3.0.3",

    "angular-resource": "1.2.10",

    "angular-cookies": "1.2.10",

    "angular-sanitize": "1.2.10",

    "angular-route": "1.2.10",

    "angular-ui-router": "0.2.7"

  },

  "devDependencies": {

    "angular-mocks": "1.2.10",

    "angular-scenario": "1.2.10"

  }

}


// angular 버전 업데이트

$ bower update 

angular-resource#1.2.10 app/bower_components/angular-resource

└── angular#1.2.10

.. 중략..

angular-scenario#1.2.10 app/bower_components/angular-scenario

└── angular#1.2.10


// ui-router 설치 1번을 선택한다 

$ bower install angular-ui-router#0.2.7 --save

    1) angular-ui-router#0.2.7 which resolved to 0.2.7

    2) angular-ui-router#~0.2.8 which resolved to 0.2.8 and has meanstack as dependants

[?] Answer: 1

angular-ui-router#0.2.7 app/bower_components/angular-ui-router

└── angular#1.2.10


   bower를 통해 ui-router를 설치 후 "grunt build" 또는 "grunt serve" 를 실행하면 index.html에 필요 파일이 자동 추가된다. 자동 추가되는 파일의 정보는 bower_components/angular-bootstrap/bower.json 파일에 지정되어 있다. 

    <!-- build:js scripts/vendor.js -->

    <!-- bower:js -->

    <script src="bower_components/jquery/jquery.js"></script>

    <script src="bower_components/angular/angular.js"></script>

    <script src="bower_components/bootstrap/dist/js/bootstrap.js"></script>

    <script src="bower_components/angular-resource/angular-resource.js"></script>

    <script src="bower_components/angular-cookies/angular-cookies.js"></script>

    <script src="bower_components/angular-sanitize/angular-sanitize.js"></script>

    <script src="bower_components/angular-route/angular-route.js"></script>

    <script src="bower_components/angular-bootstrap/ui-bootstrap-tpls.js"></script>

    <script src="bower_components/angular-ui-router/release/angular-ui-router.js"></script>

    <!-- endbower -->

    <!-- endbuild -->


  ui-router 또한 별도의 모듈이므로 app/scripts/app.js 안에 모듈 의존성을 설정한다 

'use strict';


angular.module('meanstackApp', [

  'ngCookies',

  'ngResource',

  'ngSanitize',

  'ngRoute',

  'ui.bootstrap',

  'ui.router'

])

  .config(function ($routeProvider) {

  .. 중략 ..

  });



4. FontAwesome Icon 설치

  다양한 아이콘을 사용하기 위하여 bootstrap과 별도로 fontawesom(http://fortawesome.github.io/Font-Awesome/) 라이브러리를 설치한다. 텍스트 정보를 좀 더 직관적으로 인지할 수 있도록 다양한 아이콘을 적용할 수 있다. 

$ bower install font-awesome --save

bower font-awesome#*            cached git://github.com/FortAwesome/Font-Awesome.git#4.0.3

font-awesome#4.0.3 app/bower_components/font-awesome


  설치 후 app/bower_components/font-awesome/ 폴더 밑으로 bower.json 이 존재하지 않으므로 필요한 파일을 index.html에 직접 기입해야 한다. index.html에 font-awesome.css 파일을 추가하자. 추가시 <!-- bower:css --> 영역에 넣으면 grunt build(grunt serve)시에 직접 넣은 정보는 자동 삭제되므로 <!-- bower:css --> 가 없는 <!-- build:css --> 안에 추가한다. 

     <!-- build:css styles/vendor.css -->

    <!-- bower:css -->

    <link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.css" />

    <!-- endbower -->

    <!-- endbuild -->


    <!-- build:css({.tmp,app}) styles/main.css -->

    <link rel="stylesheet" href="bower_components/font-awesome/css/font-awesome.css" />

    <link rel="stylesheet" href="styles/main.css">

    <!-- endbuild -->


  'grunt build'를 하게 되면 font-awesome의 css는 app/styles/main.css 파일로 묶이게 된다. font-awesome.css 소스를 보면 css 상위의 fonts 폴더의 파일을 참조한다. 따라서 font-awesome의 fonts 폴더안의 파일들을 app/fonts 밑으로 복사한다.

Twitter Bootstrap과 Font awesome의 css가 참조하는 파일들 목록

$ cd app/fonts

$ ls 


fontawesome-webfont.woff

fontawesome-webfont.ttf

fontawesome-webfont.svg

fontawesome-webfont.eot

FontAwesome.otf

glyphicons-halflings-regular.woff

glyphicons-halflings-regular.ttf

glyphicons-halflings-regular.svg

glyphicons-halflings-regular.eot


이제 필요한 라이브러리들이 index.html에 추가되었다. 다음장에서는 Twitter Bootstrap을 이용하여 반응형 웹 디자인(Responsive Web Design : RWD) 메뉴와 전체 화면 레이아웃을 만들어 보자.

posted by 윤영식
2013. 6. 22. 12:35 Meteor

오늘은 마지막 수업날. 미티어의 개념과 아키텍쳐 그리고 실업무 프로젝트를 위한 디렉토리 구조에 대해 프로토타입핑해 보고, Twitter Bootstrap이나 Font-Awesome을 접목시켜본다.



1. 미티어 개념 핵심

  - 웹앱의 진화 개념에서 기존의 다른 프레임워크와 차이를 보인다

  - 미티어는 클라이언트와 서버사이에 스토어인 MongoDB가 존재한다

    + WebApp v1.0 : 서버단의 rendering pc 기술

    + WebApp v1.5 : client는 SPA로 진화, server+db의 통합

    + WebApp v2.0 : client <-> db + db <-> server 로 묶인다

  

  - FireBase의 서비스를 보면서 WebApp 2.0 Meteor와 맵핑이 된다 

   + How it works

  


  - 미티어는 이것이다!

    + client <-> db 사이에서 미티어가 하는 일이 핵심 개념이다. 그러나 db <-> server 까지도 통합해 놓았다

    + server는 웹서버 또는 데이터 전달의 역할을 수행한다

    + 미티어를 중심으로 MVC가 구현된다. 

       Model - DX Area (Data eXperience)

       View  - UX Area (User or UI eXperience) 

       Controller - BX Area (Business eXperience)

   

                      <KOSTA 이복영강사님이 생각하시는 미티어의 X 영역들>



2. 프로젝트 기본 구조

  - 미티어를 설치하고 간단한 myapp 을 시작해 보자

    + myapp 디렉토리를 들어가 보면 간단 3개의 파일이 존재한다 : myapp.js, myapp.css, myapp.html

    + 단 3개의 파일을 통하여 client <-> server 코딩이 완료되었다

$ meteor create myapp

myapp: created.

To run your new app:

   cd myapp

   meteor


  - myapp 프로젝트안에서 미티어가 인식하는 디렉토리 구조

    + client, server 디렉토리 밑으로 하위 디렉토리를 만들어서 프로젝트 업무 controller별, 기능별로 나눌 수 있고, 자동 인식된다

    + 각 디렉토리를 만들고 myapp을 실업무 구조로 만들어 본다

· client – 클라이언트에서 수행되는 JavaScript 와 HTML 파일

· server – 서버에서 수해되는 JavaScript 와 HTML 파일

· common – 클라이언트와 서버에서 수행되는 JavaScript 파일

· lib –  다른 모든 JavaScript 파일보다 먼저 수행 할 JavaScript 파일

· public – static application assets such as images.



3. 실업무 구조로 만들어 보기 

  - 링크 사이트의 실습을 따라해 본다

 1) client/movies.html : html 태그를 사용하지 않고 head 와 body 만 존재한다 

<head>

  <title>myapp</title>

</head>


<body>

  <h1>Movies</h1>

  {{> moviesTemplate }}

</body>  


  2) client/moviesTemplate.html 파일 생성 : movies.html안에 포함된다 

<template name="moviesTemplate">

  <ul>

    {{#each movies}}

    <li>

      {{title}}

    </li>

    {{/each}}

  </ul>

</template>


  3) client/movies.js 파일 생성 : moview 컬렉션을 글로벌로 만든다. moviesTemplate.movies 확장 메소드를 정의한다 

Movies = new Meteor.Collection("movies");

Template.moviesTemplate.movies = function () {

  return Movies.find();

};


 4) server/movies.js 파일 생성 : 데이터가 없으면 테스트용 값을 넣는다  

// Declare server Movies collection

Movies = new Meteor.Collection("movies");


// Seed the movie database with a few movies

Meteor.startup(function () {

  if (Movies.find().count() == 0) {

    Movies.insert({ title: "Star Wars", director: "Lucas" });

    Movies.insert({ title: "Memento", director: "Nolan" });

    Movies.insert({ title: "King Kong", director: "Jackson" });

  }

});


  5) client/movieForm.html 파일 생성 및 movies.html 갱신: 무비 등록

// movieForm.html

<template name="movieForm">

  <fieldset>

    <legend>Add New Movie</legend>

    <form>

      <div>

        <label>

          Title:

          <input id="title" />

        </label>

      </div>

      <div>

        <label>

          Director:

          <input id="director" />

        </label>

      </div>

      <div>

        <input type="submit" value="Add Movie" />

      </div>

    </form>

  </fieldset>

</template>


// movies.html 

  {{> moviesTemplate }}

  {{> movieForm }}  <-- 추가



  6) client/movies.js 내역을 갱신한다 : movieForm.events 헬퍼메소드를 정의한다

Template.moviesTemplate.movies = function () {

  return Movies.find();

};


// Handle movieForm events

Template.movieForm.events = {

  'submit': function (e, tmpl) {

    // Don't postback

    e.preventDefault();


    // create the new movie

    var newMovie = {

      title: tmpl.find("#title").value,

      director: tmpl.find("#director").value

    };


    // add the movie to the DB

    Movies.insert(newMovie);

  }

};


  7) 실제값을 넣어본다 : 화면이 갱신되며, MongoDB에도 데이터가 새롭게 insert된다 : meteor의 몽고 쉘로 들어가서 확인함


$ meteor mongo

MongoDB shell version: 2.4.3

connecting to: 127.0.0.1:3002/meteor

> use meteor

switched to db meteor

> show collections

movies

system.indexes

> db.movies.find()

{ "title" : "Star Wars", "director" : "Lucas", "_id" : "xmTvZ6Lv4CazosgGi" }

{ "title" : "Memento", "director" : "Nolan", "_id" : "M6jf2LgXMhsvTXboB" }

{ "title" : "King Kong", "director" : "Jackson", "_id" : "xxZ6ynrxFPwB7jCoD" }

{ "title" : "hi ", "director" : "dowon", "_id" : "Cwri8WHudNq8sMyXe" }


  8) 심화학습

  + Movies 와 동일하게 Persons를 확장해 보자

$ meteor mongo 

> db.persons.find()

{ "name" : "Yun DoWon", "phone" : "010-1004", "_id" : "7e2Buco4sREFgjDCw" }


  

  + Meteor.Collection 생성을 lib 디렉토리로 옮기게 되면 client/movies.js, server/movies.js 에서 중복 코드를 제거할 수 있다. 

       lib/collections.js 만들기 

Movies = new Meteor.Collection("movies");

Persons = new Meteor.Collection("persons");


  + movies, persons 디렉토리로 구별한다 

  



4. Twitter Bootstrap 입히기

  - http://twitter.github.io/bootstrap/ 사이트에서 파일을 다운로드 받는다

  - bootstrap.zip 파일을 client/bootstrap 디렉토리에 푼다

  - client/persons/personsTemplate.html에서 css를 적용해 본다 

// personsTemplate.html 

<template name="personsTemplate">

  <ul>

    {{#each persons}}

    <li class="btn">

      {{name}}

    </li>

    <li class="alert">

      {{phone}}

    </li>

    {{/each}}

  </ul>

</template> 


// personForm.html

 <input class="btn" type="submit" value="Add Person" />

 


  - Font Awesome css도 넣어보자. Twitter Bootstrap처럼 수동으로 설치하지 않고 meteorite를 통해 설치한다 

    + https://github.com/nate-strauser/meteor-font-awesome 해당 사이트에서 font-awesome 을 설치해야하는 함정이... ^^

    + meteorite는 node.js의 npm과 유사하게 meteor의 package 를 관리해 준다

$ npm install -g meteorite

$ mrt add font-awesome

✓ font-awesome

    tag: https://github.com/nate-strauser/meteor-font-awesome.git#v3.2.0


Done installing smart packages


// packages 디렉토리 밑으로 font-awesome이 설치되었다

// smart.json과 smart.lock 파일은 meteorite 환경파일


  -  client/personForm.html 에 아이콘을 넣는다 

<template name="personForm">

<div class="container">

  <fieldset>

    <legend>Add New Person</legend>

    <form>

      <div>

        <label>

          Name:

          <input id="name" />

        </label>

      </div>

      <div>

        <label>

          Phone:

          <input id="phone" />

        </label>

      </div>

      <div>

        <i class="icon-male"></i> <input class="btn" type="submit" value="Add Person" />

      </div>

    </form>

  </fieldset>


  <!-- test -->

  <a class="btn" href="#">

    <i class="icon-repeat"></i> Reload</a>

  <a class="btn btn-success" href="#">

    <i class="icon-shopping-cart icon-large"></i> Checkout</a>

  <a class="btn btn-large btn-primary" href="#">

    <i class="icon-comment"></i> Comment</a>

  <a class="btn btn-small btn-info" href="#">

    <i class="icon-info-sign"></i> Info</a>

  <a class="btn btn-danger" href="#">

    <i class="icon-trash icon-large"></i> Delete</a>

  <a class="btn btn-small" href="#">

    <i class="icon-cog"></i> Settings</a>

  <a class="btn btn-large btn-danger" href="#">

    <i class="icon-flag icon-2x pull-left"></i> Font Awesome<br>Version 3.2.1</a>

  <a class="btn btn-primary" href="#">

    <i class="icon-refresh icon-spin"></i> Synchronizing Content...</a>




<참조>

  - 미티어 구조 설계하기

  - 미티어 한글번역 : http://docs-ko.meteor.com/

  - 아이콘 확장은 Font Awesome을 사용한다 : http://fortawesome.github.io/Font-Awesome/

  - 심화학습 코드 : .meteor는 포함되지 않았으니 meteor create을 하고서 첨부한다

myapp.tar



posted by 윤영식
prev 1 next