Creando un paquete Meteor

Sidebar 9.5

Porcentaje completado

En este capítulo:

  • Escribiremos un paquete Meteor para nuestra aplicación de forma local.
  • Escribiremos tests para nuestro paquete.
  • Publicaremos el paquete en el repositorio Atmosphere.
  • Durante nuestro trabajo en los errores, hemos construido un modelo reutilizable, ¿por qué no ponerlo dentro de un paquete y compartirlo con el resto de la comunidad Meteor?

    Para empezar, tenemos que asegurarnos de que tenemos una cuenta de desarrollador Meteor. Puedes hacerte una en meteor.com, pero es muy probable que ya lo hayas hecho ¡cuando te registraste para el libro! En cualquier caso, deberías saber cuál es tu nombre de usuario, porque lo utilizaremos bastante durante este capítulo.

    En este capítulo usaremos tmeasday como usuario – puedes cambiarlo por el tuyo.

    En primer lugar, necesitamos crear una estructura de carpetas para nuestro paquete. Podemos usar el comando meteor create --package tmeasday:errors para conseguirla. Fíjate que Meteor ha creado una carpeta llamada packages/tmeasday:errors/, con algunos ficheros dentro. Comenzaremos por editar package.js, el archivo que informa a Meteor de cómo debe utilizar el paquete, y los símbolos y funciones que exporta.

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

    Cuando desarrollamos un paquete para su uso en el mundo-real, es una buena práctica rellenar la sección Package.describe con la URL del repositorio Git (como por ejemplo, https://github.com/tmeasday/meteor-errors.git). De esta manera, los usuarios pueden acceder al código fuente, y (si usas GitHub) ver el README del paquete en Atmosphere.

    Vamos a añadir al paquete los tres archivos que se pasan en la llamada a add_files. Podemos usar los mismos que tenemos para Microscope, haciendo solo, unos pequeños cambios para los espacios de nombres y para dejar la API un poco más limpia:

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

    Probando el paquete con Microscope

    Vamos a probar el paquete localmente con Microscope para asegurarnos de que nuestros cambios funcionan. Para enlazar el paquete en nuestro proyecto, ejecutaremos meteor add tmeasday:errors. A continuación, debemos eliminar los archivos a los que reemplaza el nuevo paquete:

    rm client/helpers/errors.js
    rm client/templates/includes/errors.html
    rm client/templates/includes/errors.js
    
    Eliminando los archivos antiguos

    Otra cosa que debemos hacer son algunos pequeños cambios en el código de la aplicación para que use la API correcta:

      {{> header}}
      {{> meteorErrors}}
    
    client/templates/application/layout.html
    Meteor.call('postInsert', post, function(error, id) {
      if (error) {
        // display the error to the user
        Errors.throw(error.reason);
    
    
    client/templates/posts/post_submit.js
    Posts.update(currentPostId, {$set: postProperties}, function(error) {
      if (error) {
        // display the error to the user
        Errors.throw(error.reason);
    
      // show this result but route anyway
      if (result.postExists)
        Errors.throw('This link has already been posted');
    
    client/templates/posts/post_edit.js

    Commit 9-5-1

    Creado y enlazado un paquete básico.

    Una vez hechos estos cambios, deberíamos ver el mismo comportamiento que teníamos con el código sin empaquetar.

    Escribiendo Tests

    El primer paso en el desarrollo de un paquete es probarlo contra una aplicación, pero el siguiente es escribir un conjunto de tests que evalúen adecuadamente el comportamiento del paquete. Meteor incluye Tinytest, que permite ejecutar este tipo de pruebas de forma fácil y, de esta forma, tener la conciencia tranquila cuando compartimos el paquete con los demás.

    Vamos a crear un archivo que usa Tinytest para ejecutar tests contra el código de los errores.

    Tinytest.add("Errors - collection", 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", function(test, done) {
      Errors.throw('A new error!');
      test.equal(Errors.collection.find({}).count(), 1);
    
      // render the template
      UI.insert(UI.render(Template.meteorErrors), document.body);
    
      Meteor.setTimeout(function() {
        test.equal(Errors.collection.find({}).count(), 0);
        done();
      }, 3500);
    });
    
    packages/tmeasday:errors/errors_tests.js

    Con estos tests comprobamos que las funciones básicas de Meteor.Errors funcionan correctamente, así como que el código mostrado en la plantilla sigue funcionando bien.

    No vamos a cubrir los aspectos específicos sobre cómo escribir tests de paquetes (porque la API todavía no está acabada y podría cambiar mucho), pero viendo el código, puedes hacerte una idea cómo funciona.

    Para decirle a Meteor que ejecute los tests, añadimos este código a package.js

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

    Commit 9-5-2

    Tests añadidos al paquete.

    Ya podemos ejecutar los tests con:

    meteor test-packages tmeasday:errors
    
    Terminal
    Pasando todos los tests
    Pasando todos los tests

    Publicando el paquete

    Ahora, queremos liberar el paquete y ponerlo a disposición de todo el mundo. Para ello tendremos que subirlo al servidor de paquetes de Meteor y, hacerlo miembro del repositorio Atmosphere.

    Afortunadamente, es muy fácil. Entramos en el directorio del paquete, y ejecutamos meteor publish --create:

    cd packages/tmeasday:errors
    meteor publish --create
    
    Terminal

    Ahora que hemos publicado el paquete, podemos eliminarlo del proyecto y luego añadirlo de nuevo directamente:

    rm -r packages/errors
    meteor add tmeasday:errors
    
    Terminal (ejecutar desde el directorio raíz de la aplicación)

    Commit 9-5-4

    Paquete eliminado del árbol de desarrollo.

    Ahora debemos ver a Meteor descargar nuestro paquete por primera vez. ¡Bien hecho!

    Como de costumbre, asegúrate de deshacer los cambios antes de continuar (o mantenerlos, teniéndolos en cuenta en el resto del libro).