Meteor 패키지 만들기

Sidebar 9.5

번역 완료율

이 장에서는:

  • Local in-app 패키지를 작성한다.
  • 패키지에 대한 몇 가지 테스트 방법을 알아본다.
  • 작성한 패키지를 Atmosphere에 릴리즈한다.
  • 오류에 대한 재사용 가능한 패턴을 구축했는데, 이를 묶어 스마트 패키지를 만들고 이를 미티어 커뮤니티에서 공유하도록 하면 어떨까?

    첫째, 이 패키지의 구조를 만들어야 한다. 우리는 이 패키지를 packages/errors 라는 이름의 디렉토리에 넣는다. 이렇게 하면 자동으로 사용되는 커스텀 패키지가 된다(Meteor가 packages/ 디렉토리 에 symlink로 패키지를 설치한다는 사실을 알지 모르겠다).

    둘째, 그 폴더에 package.js를 만든다. 이 파일은 미티어에게 해당 패키지를 사용하는 방법과 그 패키지가 내보내는 symbol들을 알려준다.

    Package.describe({
      summary: "A pattern to display application errors to the user"
    });
    
    Package.on_use(function (api, where) {
      api.use(['minimongo', 'mongo-livedata', 'templating'], 'client');
    
      api.add_files(['errors.js', 'errors_list.html', 'errors_list.js'], 'client');
    
      if (api.export) 
        api.export('Errors');
    });
    
    packages/errors/package.js

    이 패키지에 세 개의 파일들을 추가한다. 이 파일들은 Microscope에서 가져오는데 네임스페이스를 바꾸는 것과 약간 개선된 API를 제외하면 거의 변화가 없다:

    Errors = {
      // Local (client-only) collection
      collection: new Meteor.Collection(null),
    
      throw: function(message) {
        Errors.collection.insert({message: message, seen: false})
      },
      clearSeen: function() {
        Errors.collection.remove({seen: true});
      }
    };
    
    
    packages/errors/errors.js
    <template name="meteorErrors">
      {{#each errors}}
        {{> meteorError}}
      {{/each}}
    </template>
    
    <template name="meteorError">
      <div class="alert alert-error">
        <button type="button" class="close" data-dismiss="alert">&times;</button>
        {{message}}
      </div>
    </template>
    
    packages/errors/errors_list.html
    Template.meteorErrors.helpers({
      errors: function() {
        return Errors.collection.find();
      }
    });
    
    Template.meteorError.rendered = function() {
      var error = this.data;
      Meteor.defer(function() {
        Errors.collection.update(error._id, {$set: {seen: true}});
      });
    };
    
    packages/errors/errors_list.js

    Microscope로 패키지 테스트하기

    작성한 코드가 작동하는 지를 확인하기 위해 로컬에서 Microscope로 테스트를 진행한다. 패키지를 프로젝트에 연동하기 위해 meteor add errors 명령을 수행한다. 그 다음, 이 새 패키지로 인해서 필요없게 된 기존의 파일들을 삭제한다:

    $ rm client/helpers/errors.js
    $ rm client/views/includes/errors.html
    $ rm client/views/includes/errors.js
    
    bash 콘솔에서 예전 파일들을 삭제하기

    한 가지 더 할 일은 올바른 API를 사용하도록 약간 수정을 하는 것이다:

    Router.onBeforeAction(function() { Errors.clearSeen(); });
    
    lib/router.js
      {{> header}}
      {{> meteorErrors}}
    
    client/views/application/layout.html
    Meteor.call('post', post, function(error, id) {
      if (error) {
        // display the error to the user
        Errors.throw(error.reason);
    
    
    client/views/posts/post_submit.js
    Posts.update(currentPostId, {$set: postProperties}, function(error) {
      if (error) {
        // display the error to the user
        Errors.throw(error.reason);
    
    client/views/posts/post_edit.js

    Commit 9-5-1

    기본적인 오류 패키지를 만들고 이를 연동했다.

    이 수정작업이 완료되고 나면, 패키지 이전의 상태로 되돌려야 한다.

    테스트 작성하기

    패키지를 개발하는 첫 단계는 애플리케이션에서 테스트하는 것이지만, 그 다음 단계는 패키지의 작동을 적절하게 테스트하는 테스트 세트를 작성하는 것이다. 미티어 자체에 Tinytest(빌트인 패키지 테스터)가 들어있는 데, 이것을 이용하면 테스트를 쉽게 할 수 있고, 다른 사람들과 이 패키지를 공유할 때 평정심을 유지할 수 있다.

    오류 코드로 몇 가지 테스트를 수행하기 위해 Tinytest를 사용하는 테스트 파일을 만들어보자:

    Tinytest.add("Errors collection works", function(test) {
      test.equal(Errors.collection.find({}).count(), 0);
    
      Errors.throw('A new error!');
      test.equal(Errors.collection.find({}).count(), 1);
    
      Errors.collection.remove({});
    });
    
    Tinytest.addAsync("Errors template works", function(test, done) {  
      Errors.throw('A new error!');
      test.equal(Errors.collection.find({seen: false}).count(), 1);
    
      // render the template
      OnscreenDiv(Spark.render(function() {
        return Template.meteorErrors();
      }));
    
      // wait a few milliseconds
      Meteor.setTimeout(function() {
        test.equal(Errors.collection.find({seen: false}).count(), 0);
        test.equal(Errors.collection.find({}).count(), 1);
        Errors.clearSeen();
    
        test.equal(Errors.collection.find({seen: true}).count(), 0);
        done();
      }, 500);
    });
    
    packages/errors/errors_tests.js

    이 테스트에서는 기본함수인 Meteor.Errors이 동작하는 지를 검사한다. 뿐만 아니라 템플릿에서 rendered 코드가 여전히 기능하는 지에 대해서도 검사한다.

    미티어 패키지 테스트를 작성하는 과정의 세세한 것까지 여기서 다루지는 않을 것이다(API는 아직 확정된 것이 아니고 매우 유동적이다). 하지만 희망하건데 이것의 작동 방법은 자체로 입증이 될 것이다.

    미티어에게 package.js에서의 테스트 실행 방법을 지시하려면 다음 코드를 사용하기 바란다:

    Package.on_test(function(api) {
      api.use('tmeasday:errors', 'client');
      api.use(['tinytest', 'test-helpers'], 'client');  
    
      api.add_files('errors_tests.js', 'client');
    });
    
    packages/errors/package.js

    Commit 9-5-2

    패키지에 테스트 기능을 추가했다.

    그러면 다음 명령어로 테스트를 실행할 수 있다:

    $ meteor test-packages tmeasday:errors
    
    터미널
    모든 테스트 통과
    모든 테스트 통과

    패키지 릴리즈

    이제, 패키지를 릴리즈하여 모두가 이를 이용할 수 있게 하려고 한다. 그렇게 하려면 Atmosphere에 올리면 된다.

    우선, smart.json을 추가하여 Meteor와 Atmosphere에 그 패키지에 대한 중요한 상세 내용을 알린다:

    {
      "name": "errors",
      "description": "A pattern to display application errors to the user",
      "homepage": "https://github.com/tmeasday/meteor-errors",
      "author": "Tom Coleman <tom@thesnail.org>",
      "version": "0.1.0",
      "git": "https://github.com/tmeasday/meteor-errors.git",
      "packages": {
      }
    }
    
    packages/errors/smart.json

    Commit 9-5-3

    smart.json 파일을 추가했다.

    그 패키지에 대한 정보를 제공하기 위하여 몇 가지 기본적인 메타데이터를 넣는다. 여기에는 이것의 주요 기능, 호스트 git 주소, 그리고 초기 버전 정보가 포함된다. 만약 이 패키지가 다른 Atmosphere 패키지에 의존한다면, 그 의존성 정보를 기술하는 "packages" 섹션을 추가한다.

    이 모두가 마무리되면 릴리즈는 쉽다. git 저장소를 만들고 원격 git 서버로 올리고, smart.json에 그 주소에 대한 연결정보를 추가한다.

    GitHub에서 이 작업을 하려면, 우선 새 저장소를 만든 다음, 그 저장소에서 패키지의 코드를 얻는 일반적인 과정을 따른다. 그리고, meteor release 명령어를 사용하여 게재한다:

    $ git init
    $ git add -A
    $ git commit -m "Created Errors Package"
    $ git remote add origin https://github.com/tmeasday/meteor-errors.git
    $ git push origin master
    $ meteor release .
    Done!
    
    터미널 (`packages/errors` 내에서 실행한다)

    주: 패키지 이름은 유일해야 한다. 위의 내용을 문자 그대로 따라하여 동일한 패키지 이름을 사용하면, 충돌이 발생해서 작동하지 않게 될 것이다. 미래에 Atmosphere는 저자에 따른 네임스페이스를 가지게 될 것이므로, 이 이름이 바뀔 수 있다는 점을 감안하기 바란다.

    두 번째 주: http://atmosphere.meteor.com에 로그인하여 meteor release를 호출할 때 커맨드 라인에서 입력할 username과 비밀번호를 만들어야 한다.

    이제 패키지가 릴리즈되면, 프로젝트에서 그것을 제거하고 그것을 직접 추가하여 복원한다:

    $ rm -r packages/errors
    $ meteor add errors
    
    터미널 (앱의 루트 경로에서 실행한다)

    Commit 9-5-4

    개발 트리에서 패키지를 삭제했다.

    이제 Meteor에서 패키지를 다운로드하는 것을 처음으로 볼 수 있을 것이다. 잘했다!