Criando um Pacote Meteorite

Lateral 9.5

Porcentagem Traduzida

Neste capítulo, você irá:

  • Escreva um pacote local para sua aplicação.
  • Escreva alguns testes para seu pacote.
  • Disponibilize seua pacote no Atmosphere.
  • Nós construímos um padrão re-utilizável com o nosso trabalho com erros, então porque não envovê-lo num pacote inteligente e compartilhá-lo com o resto da comunidade Meteor?

    Primeiro nós precisamos criar alguma estrutura para o nosso pacote residir. Nós pomos o pacote num diretório chamado packages/errors. Isto cria um pacote personalizado que é automaticamente utilizado. (Você pode ter notado que o Meteorite instala pacotes através de symlinks no diretório packages/).

    Segundo, nós criaremos package.js nessa pasta, o arquivo que informa ao Meteor como o pacote deve ser utilizado, e os símbolos que ele exporta.

    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

    Vamos adicionar três arquivos ao pacote. Nós podemos puxar esses arquivos do Microscopoe sem muita mudança exceto por algum namespacing apropriado e uma API ligeiramente mais limpa:

    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

    Testando o pacote com Microscope

    Agora nós testaremos as coisas localmente com Microscope para assegurar que o nosso código modificado funcione. Para ligar o pacote ao nosso projeto, nós rodamos meteor add errors. Então, nós precisamos deletar os arquivos existentes que se tornaram redudantes devido ao novo pacote:

    $ rm client/helpers/errors.js
    $ rm client/views/includes/errors.html
    $ rm client/views/includes/errors.js
    
    removing old files on the bash console

    Uma outra coisa que nós precisamos fazer é algumas pequenas atualizações para utilizar a API correta:

    Router.before(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

    Created basic errors package and linked it in.

    Uma vez que essas mudanças forem feitas, nós devemos ter nosso comportamento original pré-pacote de volta.

    Escrevendo testes

    O primeiro passo em desenvolver um pacote é testá-lo num aplicativo, mas o próximo é escrever um grupo de teste que testa propriamente o comportamento do pacote. O Meteor em si vem com Tinytest (pacote nativo de testagem), que torna fácil rodar tais testes e manter a paz espiritual ao compartilhar nosso pacote com outros.

    Vamos criar um arquivo de teste que usa Tinytest para rodar alguns testes contra a nossa base de código para errors:

    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

    Nesses testes nós estamos checando se as funções básicas de Meteor.Errors estão funcionando, assim como checando duas vezes que o código rendered no template ainda está funcionando.

    Nós não cobriremos as especificidades de se escrever testes para pacotes Meteor aqui (já que a API não está finalizada e sim em alto fluxo), mas felizmente é bem auto-explicativo como funciona.

    Para dizer ao Meteor como rodar os teste em package.js, use o código seguinte:

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

    Commit 9-5-2

    Added tests to the package.

    Então nós podemos rodar os testes com:

    $ meteor test-packages errors
    
    Terminal
    Passing all tests
    Passing all tests

    Lançando o pacote

    Agora, nós queremos lançar o pacote e torná-lo disponível para o mundo. Nós fazemos isso pondo-o em Atmosphere.

    Primeiro, nós precisamos adicionar um smart.json, para dizer ao Meteorite e Atmosphere os detalhes importantes do pacote:

    {
      "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

    Added a smart.json

    Nós pomos alguma meta-informação básica para prover informação sobre o pacote, incluindo o que ele faz, a localização git onde nós vamos hospedá-lo, e um número inicial de versão. Se nosso pacote necessita de outros pacotes Atmosphere, nós também podemos utilizar o segmento "pacotes" para informar as dependências.

    Uma vez que tudo isto esteja no lugar, lançar é fácil. Nós precisaremos criar um repositório git, empurrar a um servidor git remote em algum lugar, e linkar para essa localização no nosso smart.json.

    O processo de fazer isso para o GitHub é primeiro criar um novo repositório, então seguir a prática padrão para pegar o código do pacote de dentro do repositório. Então, nós usamos o comando mrt release para publicá-lo:

    $ 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
    $ mrt release .
    Done!
    
    Terminal (run from within `packages/errors`)

    Note: nome de pacotes devem ser únicos. Se você está seguindo palavra-por-palavra e usar o mesmo nome de pacote, haverá um conflito e não funcionará. No futuro a Atmosphere separará os pacotes com nome de autor, então você pode esperar que isso mude.

    Outra coisa: Você precisará logar em http://atmosphere.meteor.com e criar um username e senha com os quais você entrará na linha de comando quando você chamar mrt release ..

    Agora que o pacote foi lançado, nós podemos deletá-lo do nosso projeto e então adicioná-lo de volta diretamente usando Meteorite:

    $ rm -r packages/errors
    $ mrt add errors
    
    Terminal (run from the top level of the app)

    Commit 9-5-4

    Removed package from development tree.

    Agora nós devemos ver o Meteorite fazer download do nosso pacote pela primeira vez. Parabéns!