시작하기

2

번역 완료율

이 장에서는:

  • Meteor를 설치한다.
  • Meteor 패키지의 다섯가지 형식에 대하여 알아본다.
  • Meteor 앱의 파일 구조를 설정한다.
  • 첫 인상은 중요하다. 미티어의 설치과정은 비교적 힘들지 않을 것이다. 대부분의 경우는 5분이내에 설치하고 실행할 수 있다.

    먼저, 터미널 윈도우를 열고 다음과 같이 입력하여 미티어를 설치한다:

    curl https://install.meteor.com | sh
    

    이것으로 meteor 실행파일이 시스템에 설치되고, 미티어를 사용할 준비가 된 것이다.

    미티어를 설치하지 않기

    미티어를 독자의 컴퓨터에 설치할 수 없다면(혹은 설치를 원하지 않으면), Nitrous.io를 방문하여 살펴보기를 권한다.

    Nitrous.io는 앱을 실행하거나 브라우저에서 바로 코드를 편집하게 하는 서비스이다. 우리는 독자가 설치하는데 도움이 되는 간단한 안내서를 작성하여 제공한다.

    이 안내서의 “Installing Meteor” 섹션까지 읽은 다음, 이 장의 “간단한 앱 만들기” 섹션에서 시작하여 이 책을 다시 따라가면 된다.

    간단한 앱 만들기

    이제 Meteor를 설치하였으니, 앱을 만들어보자. Meteor의 명령어 도구인 meteor를 사용한다:

    meteor create microscope
    

    이 명령어는 미티어를 다운로드하고, 기본적인 설정을 수행한 다음, 미티어 프로젝트를 사용할 수 있는 상태로 만든다. 실행이 완료되면, microscope/ 디렉토리에서 아래 파일들을 볼 수 있다:

    microscope.css  
    microscope.html 
    microscope.js   
    

    미티어가 만든 이 앱은 몇 가지 단순한 패턴을 보여주는 간단한 보일러플레이트 애플리케이션이다.

    이 앱이 기능은 별로 없어도, 실행할 수는 있다. 이 앱을 실행하려면 터미널에서 다음을 입력하면 된다:

    cd microscope
    meteor
    

    이제 브라우저에서 http://localhost:3000/ (또는 http://0.0.0.0:3000/)을 입력하면 다음과 같은 화면을 볼 수 있다:

    미티어에서의 Hello World.
    미티어에서의 Hello World.

    Commit 2-1

    기본적인 microscope 프로젝트를 생성했다.

    축하한다! 처음으로 미티어 앱을 실행하였다. 그리고, 이 앱을 중단하려면, 앱이 실행 중인 터미널에서 ctrl+c를 누르면 된다.

    또한 Git을 사용한다면, git init으로 이 저장소를 초기화할 적절한 시점이다.

    Meteorite여 안녕

    한 때, 미티어가 Meteorite라는 이름을 가지는 외부 패키지 관리자에 의존하던 때가 있었다. Meteor 버전 0.9.0 이후로 Meteorite는 Meteor 본체로 흡수되어 더 이상 존속하지 않게 되었다.

    그러므로 이 책에서나 또는 미티어 관련 자료를 찾아보다가 Meteorite의 mrt 명령어 도구에 대한 언급이 있다면, 이를 meteor로 바꾸면 된다.

    패키지 추가

    이번에는 미티어의 패키지 시스템을 이용하여 프로젝트에 Bootstrap 프레임워크를 추가할 것이다.

    이것은 직접 CSS와 JavaScript 파일을 직접 추가하는 보통의 방법과 다를 것이 없지만, 미티어 커뮤니티의 한 사람인 Andrew Mao의 도움을 받아 항상 최신 상태로 유지한다 (mizzao:bootstrap-3의 “mizzao”는 패키지 제작자의 username이다).

    또한 Underscore 패키지도 추가한다. Underscore는 JavaScript 유틸리티 라이브러리로 JavaScript 데이터 구조를 다룰 때 매우 유용하다.

    이 글을 쓸 때까지는, underscore 패키지는 여전히 “공식” 미티어 패키지의 일부이어서, 제작자가 없다.

    meteor add mizzao:bootstrap-3
    meteor add underscore
    

    Bootstrap 3를 추가하는 것에 유의하기 바란다. 이 책의 일부 화면은 Bootstrap 2를 적용했던 Microscope의 이전 버전에서 가져온 것으로 다소 다르게 보일 수 있다.

    Commit 2-2

    Bootstrap과 underscore 패키지를 추가했다.

    Bootstrap 패키지를 추가하자마자 앱의 외형이 바뀌는 것을 볼 수 있을 것이다:

    Bootstrap 적용 후
    Bootstrap 적용 후

    외부 자원을 포함하는 “전통적인” 방식과는 달리, 어떤 CSS 파일이나 JavaScript 파일을 링크시킬 필요는 없다. 왜냐면 미티어는 모든 것을 알아서 해주기 때문이다. 이것은 미티어 패키지의 많은 잇점 중의 하나일 뿐이다.

    패키지에 대하여

    미티어에서 패키지에 대하여 언급할 때는, 보다 구체적으로 지칭한다. 미티어에서는 다섯가지 형식의 패키지를 사용한다:

    • 미티어 core는 여러 개의 코어 패키지들로 나누어진다. 이들은 모든 미티어 앱에 포함된다. 여기는 신경쓸 것 없다.
    • 정규 미티어 패키지는 (이들이 클라이언트와 서버 양쪽에서 동작한다는 의미로) “isopacks” 또는 동형 패키지(isomorphic packages)라 부른다. accounts-uiappcache와 같은 퍼스트파티 패키지는 미티어 코어팀에서 담당하며 미티어에 포함되어 있다.
    • 써드파티 패키지는 다른 사용자들이 개발한 isopack으로서 미티어 패키지 서버에 업로드되어 있는 것을 가리킨다. 이들은 Atmosphere나 또는 meteor search 명령어로 찾아볼 수 있다.
    • 로컬 패키지는 여러분이 직접 작성한 패키지로 /packages 디렉토리에 넣는다.
    • NPM 패키지(Node Packaged Modules)는 Node.js 패키지이다. 이들은 미티어에서 단독으로 작동하지는 않지만, 위의 네 가지 형식의 패키지 내부에서 사용될 수 있다.

    미티어 앱의 파일구조

    코딩을 시작하기에 앞서, 프로젝트를 적절하게 구성해야 한다. 깔끔한 빌드를 위해 microscope 디렉토리에서 microscope.html, microscope.js, 그리고 microscope.css를 삭제하라.

    다음, /microscope 디렉토리의 하위에 4개의 서브 디렉토리를 생성하라: /client, /server, /public, 그리고 /lib.

    그 다음엔, 빈 파일 main.htmlmain.js파일을 /client 디렉토리에 만든다. 지금 앱이 동작하지 않는 것은 걱정할 것 없다. 다음 장에서 이 파일들의 내부를 채울 것이다.

    이 디렉토리 중의 몇 개는 특별하다. 코드의 실행에 대하여 이야기하자면, 미티어에는 다음과 같은 규칙이 있다:

    • 서버에서만 실행되는 코드는 /server 디렉토리에 넣는다.
    • 클라이언트에서만 실행되는 코드는 /client 디렉토리에 넣는다.
    • 그 밖의 모든 것은 클라이언트와 서버 양쪽 모두에서 실행된다.
    • 정적 자원들(fonts, images, 등)은 /public 디렉토리에 넣는다.

    그리고 미티어가 파일을 로드하는 순서를 알아두면 또한 유용할 것이다:

    • /lib 디렉토리에 있는 파일들은 그 밖의 다른 모든 파일들 보다 먼저 로드된다.
    • main.*의 이름을 가진 파일들은 그 밖의 다른 모든 파일들 보다 나중에 로드된다.
    • 그 밖의 모든 파일들은 파일명의 알파벳 순으로 로드된다.

    미티어에 위와 같은 규칙이 있지만, 원하지 않으면 앱의 구성에서 미리 정해진 파일구조를 사용하도록 강제하는 것은 아니다. 우리가 제안하는 구조는 우리의 방식일 뿐, 공식적으로 채택된 규정은 아니다.

    이에 대하여 더 상세한 정보를 원하면 공식 Meteor 문서를 살펴보기를 권한다.

    Meteor는 MVC인가?

    Ruby on Rails 같은 프레임워크에서 미티어로 옮겨왔다면, 미티어 앱이 MVC (Model View Controller) 패턴을 채택하는 지 궁금해 할 것이다.

    짧게 답변한다면 “아니오"이다. Rails와는 달리, 미티어는 앱에 미리 정해진 구조를 강제하지 않는다. 그러므로 이 책에서는 우리가 가장 이해하기 쉬운 방식으로 코드를 배치할 것이며, (MVC 같은) 두문자어들에 대하여는 너무 걱정할 것 없다.

    Public은 없다?

    그렇다. 우리는 거짓말을 했다. Microscope 앱은 정적자원을 사용하지 않으니 public/ 디렉토리가 필요없다! 하지만, 대부분의 다른 앱들은 최소한 몇 개의 이미지는 포함할테니, 이것을 다룰 필요는 있다고 생각했다.

    그런데, 숨은 .meteor 디렉토리도 보았는지 모르겠다. 이곳은 미티어가 자체 코드를 저장하는 곳인데, 여기에 있는 코드를 수정하는 것은 보통은 매우 나쁜 발상이다. 이에 대한 유일한 예외는 .meteor/packages.meteor/release 파일들인데, 이들은 각각 스마트 패키지와 사용할 미티어 버전을 기술하는데 사용된다. 패키지를 추가하거나 미티어 릴리즈를 변경할 때, 이 파일들을 검사한다면 도움이 될 것이다.

    언더스코어 대 카멜표기

    오래된 언더스코어(my_variable) 대 카멜케이스(myVariable) 논쟁에 대하여 할 수 있는 말은, 어떤 것을 선택하든 계속 고수한다면 별 상관이 없다는 것이다.

    이 책에서 카멜케이스 방식을 사용하는 이유는 보편적으로 JavaScript에서 사용되는 방식(따지고 보면, JavaScript이지 java_script가 아니다!)이기 때문이다.

    이 규칙의 유일한 예외는 파일명인데, 여기서는 언더스코어 방식(my_file.js)을 사용하며, CSS 클래스의 경우는 하이픈 방식(.my-class)을 사용한다. 이 이유는 파일시스템의 경우는, 언더스코어가 가장 일반적이기 때문이며, 반면에 CSS 문법에서는 이미 하이픈(font-family, text-align, 등)을 사용하기 때문이다.

    CSS 다루기

    이 책은 CSS에 관한 것이 아니다. 그러므로, 스타일링을 상세하게 다루어 진도가 느려지지 않도록, 처음부터 전체 스타일시트를 제공하기로 했다. 그러니 이것에 대하여 다시 걱정할 일은 없다.

    미티어가 CSS를 자동으로 로드하고 최적화하므로, 다른 정적 자원들과는 다르게 /public 디렉토리가 아닌 /client 디렉토리에 넣는다. 바로 client/stylesheets/ 디렉토리를 만들고, 이 style.css 파일을 넣어라:

    .grid-block, .main, .post, .comments li, .comment-form {
      background: #fff;
      -webkit-border-radius: 3px;
      -moz-border-radius: 3px;
      -ms-border-radius: 3px;
      -o-border-radius: 3px;
      border-radius: 3px;
      padding: 10px;
      margin-bottom: 10px;
      -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.15);
      -moz-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.15);
      box-shadow: 0 1px 1px rgba(0, 0, 0, 0.15); }
    
    body {
      background: #eee;
      color: #666666; }
    
    .navbar {
      margin-bottom: 10px; }
      /* line 32, ../sass/style.scss */
      .navbar .navbar-inner {
        -webkit-border-radius: 0px 0px 3px 3px;
        -moz-border-radius: 0px 0px 3px 3px;
        -ms-border-radius: 0px 0px 3px 3px;
        -o-border-radius: 0px 0px 3px 3px;
        border-radius: 0px 0px 3px 3px; }
    
    #spinner {
      height: 300px; }
    
    .post {
      /* For modern browsers */
      /* For IE 6/7 (trigger hasLayout) */
      *zoom: 1;
      position: relative;
      opacity: 1; }
      .post:before, .post:after {
        content: "";
        display: table; }
      .post:after {
        clear: both; }
      .post.invisible {
        opacity: 0; }
      .post.instant {
        -webkit-transition: none;
        -moz-transition: none;
        -o-transition: none;
        transition: none; }
      .post.animate{
        -webkit-transition: all 300ms 0ms;
        -webkit-transition-delay: ease-in;
        -moz-transition: all 300ms 0ms ease-in;
        -o-transition: all 300ms 0ms ease-in;
        transition: all 300ms 0ms ease-in; }
      .post .upvote {
        display: block;
        margin: 7px 12px 0 0;
        float: left; }
      .post .post-content {
        float: left; }
        .post .post-content h3 {
          margin: 0;
          line-height: 1.4;
          font-size: 18px; }
          .post .post-content h3 a {
            display: inline-block;
            margin-right: 5px; }
          .post .post-content h3 span {
            font-weight: normal;
            font-size: 14px;
            display: inline-block;
            color: #aaaaaa; }
        .post .post-content p {
          margin: 0; }
      .post .discuss {
        display: block;
        float: right;
        margin-top: 7px; }
    
    .comments {
      list-style-type: none;
      margin: 0; }
      .comments li h4 {
        font-size: 16px;
        margin: 0; }
        .comments li h4 .date {
          font-size: 12px;
          font-weight: normal; }
        .comments li h4 a {
          font-size: 12px; }
      .comments li p:last-child {
        margin-bottom: 0; }
    
    .dropdown-menu span {
      display: block;
      padding: 3px 20px;
      clear: both;
      line-height: 20px;
      color: #bbb;
      white-space: nowrap; }
    
    .load-more {
      display: block;
      -webkit-border-radius: 3px;
      -moz-border-radius: 3px;
      -ms-border-radius: 3px;
      -o-border-radius: 3px;
      border-radius: 3px;
      background: rgba(0, 0, 0, 0.05);
      text-align: center;
      height: 60px;
      line-height: 60px;
      margin-bottom: 10px; }
      .load-more:hover {
        text-decoration: none;
        background: rgba(0, 0, 0, 0.1); }
    
    .posts .spinner-container{
      position: relative;
      height: 100px;
    }
    
    .jumbotron{
      text-align: center;
    }
    .jumbotron h2{
      font-size: 60px;
      font-weight: 100;
    }
    
    @-webkit-keyframes fadeOut {
      0% {opacity: 0;}
      10% {opacity: 1;}
      90% {opacity: 1;}
      100% {opacity: 0;}
    }
    
    @keyframes fadeOut {
      0% {opacity: 0;}
      10% {opacity: 1;}
      90% {opacity: 1;}
      100% {opacity: 0;}
    }
    
    .errors{
      position: fixed;
      z-index: 10000;
      padding: 10px;
      top: 0px;
      left: 0px;
      right: 0px;
      bottom: 0px;
      pointer-events: none;
    }
    .alert {
              animation: fadeOut 2700ms ease-in 0s 1 forwards;
      -webkit-animation: fadeOut 2700ms ease-in 0s 1 forwards;
         -moz-animation: fadeOut 2700ms ease-in 0s 1 forwards;
      width: 250px;
      float: right;
      clear: both;
      margin-bottom: 5px;
      pointer-events: auto;
    }
    .posts .spinner-container{
        position: relative;
        height: 100px;
    }
    
    client/stylesheets/style.css

    Commit 2-3

    재구성된 파일 구조.

    CoffeeScript에 대하여

    이 책은 순수 JavaScript로 작성될 것이다. 하지만, CoffeeScript를 선호한다면, 미티어가 지원하는 기능을 이용하기 바란다. 그저 CoffeeScript 패키지를 추가하고 진행하면 된다:

    meteor add coffeescript