Creating a Meteorite Package

Randfenster 9.5

Zu ...% übersetzt

In diesem Kapitel wirst du:

  • Ein lokales in-App Package schreiben.
  • Tests für dein Package schreiben.
  • Das Package auf Atmosphere publizieren.
  • Wir haben ein wiederverwendbares Pattern in unserer Error-Anzeige, deshalb wollen wir das in ein Smartpackage verpacken und mit der Meteor Community teilen.

    Zuerst müssen wir eine Struktur für unser Package kreieren. Wir legen das Package in ein Ordner namens packages/errors/. Dies kreiert ein custom Package das automatisch von der App benutzt wird. (Vielleicht ist dir aufgefallen dass Meteorite Packages via Symlinks in den packages/ Ordner hineinspeichert).

    Dann speichern wir eine package.js in diesen Ordner ab. Dieses File gibt Meteor Auskunft darüber, wie das Package benutzt werden soll.

    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

    Nun fügen wir drei Files dem Package hinzu. Wir können diese Files ohne grosse Änderungen aus der bestehenden Microscope App hinausziehen, lediglich den Namespace und die API müssen wir leicht anpassen:

    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

    Das Package in Microscope ausprobieren

    Wir werden nun das Ganze lokal mit Microscope ausprobieren, um sicherzustellen, dass unser geänderter Code auch funktioniert. Um das Package in das Projekt zu linken müssen wir meteor add errors ausführen. Dann müssen wir die existierenden Files die in der Zwischenzeit redundant geworden sind entfernen:

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

    Was wir auch noch machen müssen, ist unsere API leicht anpassen:

    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.

    Sobald diese Änderungen vorgenommen sind, sollten wir unsere ursprüngliche Funktionalität wieder haben.

    Tests schreiben

    Der erste Schritt beim Development ist das Package in eine App zu integrieren. Der nächste Schritt ist dann, einen Test zu Schreiben, um das Package und sein Verhalten zu testen. Meteor hat eine built-in Testing Suite (Tynitest), die es einfach macht, solche Tests auszuführen und uns mit gutem Gewissen unseren Code mit anderen teilen lässt.

    Lass uns einen Test mit Tinytest schreiben, der die “Errors”-Codebase testet.

    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

    In diesen Tests überprüfen wir die grundsätzlichen Meteor.Errors Funktionen und als Doppelcheck, dass der Code im Template immer noch funktioniert.

    Wir beschäftigen uns hier nicht mit den Spezifikationen wie man Meteor Packages testet (die API ist noch nicht ganz fertiggestellt und ändert zur Zeit täglich), aber hoffentlich ist das Arbeitsprinzip zu weiten Graden selbsterklärend.

    Um Meteor mitzuteilen wie es die Tests in package.js ausführen soll, benützen wir folgenden Code:

    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.

    Dann können wir die eigentlichen Tests wie folgt laufen lassen:

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

    Das Package publizieren

    Jetzt wollen wir das Package publizieren, um es mit der Meteor Welt zu teilen. Dies machen wir über die Meteor Package Plattform Atmosphere.

    Zuerst müssen wir ein smart.json hinzufügen, damit Atmosphere die wichtigen Details unseres Packages kennt.

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

    Wir schreiben einige grundsätzliche Metadaten, um Informationen über das Package zur Verfügung zu stellen. Dies wären: Informationen über was es tut, die git location wo wir es hosten und eine initiale Verisonsnummer. Wenn unser Package Abhängigkeiten zu anderen Atmosphere Packages hat, könnten wir auch die “packages” section benützen, um diese Abhängigkeiten festzulegen.

    Wenn das alles an Ort und Stelle ist, ist das Publizieren einfach. Wir müssen ein Git Repository erstellen, zu einem Remote Git pushen und auf diese location in der smart.json verlinken.

    Der Prozess dafür auf GitHub ist: Zuerst das neue Repository erstellen und dann dem Standard Workflow zum Zurverfügungstellen des Codes im Repository folgen. Dann können wir den mrt release Befehl brauchen um es zu Publizieren.

    $ 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`)

    Bemerkung: Package Namen müssen einzigartig sein. Wenn du bisher Wort-für-Wort gefolgt bist und denselben Package Namen benutzt, wird es einen Konflikt geben. In Zukunft wird Atmosphere allerdings einen Autoren-Namespace haben. Du kannst also damit rechnen, dass es da noch Änderungen gibt.

    Zweite Bemerkung: Du musst auf http://atmosphere.meteor.com/accounts einloggen und einen Usernamen und Password erstellen. Diese brauchst du wenn du auf der Command Line mrt release aufrufst.

    Jetzt wenn das Package publiziert ist, können wir es aus dem Projekt löschen und wieder über Meteorite als offizielles Package einfügen:

    $ 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.

    Jetzt sollte Meteorite unser Package zum ersten mal herunterladen. Herzliche Gratulation!