Meteor

Meteor – Open Source Plattform für Web-Apps und Mobile-Apps

Von am 08.12.2014

Dieser Artikel beschäftigt sich mit Meteor, einer Open Source Plattform zum Erstellen von Webanwendungen, und erklärt – Schritt für Schritt – wie man mit Meteor eine CRUD-Anwendung schreiben kann.

Was ist Meteor?

Meteor ist eine komplette Open Source Plattform zum Erstellen von Webanwendungen, aber auch um mobile Anwendungen zu erstellen, unter Verwendung von purem JavaScript. Es ist ein Web-Framework und verwendet als Basis Node.js (selbst ein low-level Framework). Meteor wurde im Dezember 2011 vorgestellt und ist seit 28.10.2014 in Version 1.0 verfügbar.

Das Entwicklerteam hat sich zum Ziel gesetzt, Entwicklung von Webanwendungen radikal zu vereinfachen. Meteor wird clientseitig und serverseitig verwendet, das kennt man ja schon von Node.js. Clientseitiger Code kann so geschrieben werden, als würde er am Server ausgeführt werden.

Features

  • Echtzeit
    Mit Meteor können Echtzeitanwendungen erstellt werden, die reaktionsschnell sind. Daten werden live aktualisiert – ändert sich die Datenbank, ändert sich auch das Interface
  • Wenig Code
    Meteor benötigt weniger Code, als mit anderen Programmierplaftformen
  • Eine Sprache
    Sowohl am Client als auch am Server wird JavaScript verwendet
  • Offline Verwendung
    Wenn die Verbindung zum Server verloren geht, kann die Anwendung trotzdem weiter verwendet werden (solange kein Page-Reload stattfindet).  Ist die Verbindung wieder hergestellt, werden die Daten zum Server gesendet und aktualisiert.
  • Packages
    Verschiedenste Packages können am Server, Client oder auf mobilen Geräten verwendet werden. Es ist z.B. möglich “npm” von Node.js zu installieren.
  • App Umwandlung
    Mit Meteor kann die Anwendung ganz leicht in eine App für den AppStore bzw. Google Play verwandelt werden. Meteor integriert dazu Phonegap/Cordova und mit ein paar Commands ist es möglich die App am Smartphone zu starten.

Anforderungen

Um Meteor verwenden zu können, benötigt man mindestens OS X (10.6, Snow Leopard) oder Linux. Für Windows gibt es noch keine offizielle Unterstüztung, es wird jedoch breits an einer offiziellen Installation gearbeitet. Für diesen Testbericht von Meteor wurde CrunchBang Linux 11 “Waldorf” (#!) verwendet.

Installation

Die Installation ist einfach:

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

Nachdem dieser Befehl im Terminal ausgeführt wurde, kanns auch schon losgehn.

Installation von Meteor und einer Demoapplikatoin (in diesem Fall heißt sie "my_cool_app")

Installation von Meteor und Anweisungen um eine Demoapplikatoin zu installieren (in diesem Fall heißt sie “my_cool_app”)

Wenn cURL nicht installiert ist, dann einfach mit

# apt-get update
# apt-get install curl

nachinstallieren.

Demo

Nach der installation kann man mit

# meteor create ~/demo
# cd demo
# meteor

im Home Verzeichnis ein Projekt im Ordner “demo” erstellen. Mit `cd demo` wird in das Verzeichnis gewechselt und der Befehl `meteor` startet die Anwendung.

Demo App starten

Demo App starten

Ruft man jetzt im Browser “http://localhost:3000” auf kommt man zur Anwendung. Wie eingangs erwähnt, kann man in einer Datei sowohl Server als auch Client Code schreiben. Ein Blick in die Datei “demo.js” zeigt einen Client-Block und einen Server-Block. Ändert man Zeile 21 wie unten beschrieben, wird beim ersten  Aufruf der Seite auf der Konsole eine Nachricht ausgegeben. Beim Speichern der Datei wird die Anwendung automatisch neu kompiliert und es ist nicht notwendig den Browser zu aktualisieren, die Änderungen sollte man sofort sehen.

if (Meteor.isServer) {
  Meteor.startup(function () {
    console.log('Hello, from Server!');
  });
}

Außerdem sieht man in der “demo.html” die Verwendung von Template Tags. Meteor verwendet dazu Spacebars, eine Template Sprache die von HandlebarsJS inspiriert wurde. Die Datei enthält außerdem weder einen Doctype noch das HTML-Tag. Diese Template Dateien sind nämlich nur Teile der Seite die dann am Ende dabei rauskommt. Alles was im Head steht wird dann zum HTML hinzugefügt, dass zum Client gesendet wird. Daselbe gilt auch für alles was im Body-Tag steht. Alles was in Template-Tags steht wird zu Meteor-Templates umgewandelt und kann dann in der JavaScript-Datei mit `Template.tplName` referenziert werden. Variablen bzw. Daten können in die Templates durch `helpers` geschrieben werden. Variablen werden in Spacebars mit `{{varName}}` referenziert und Templateaufrufe mit `{{> tplName}}`.

Die Demo-App im Browser

Die Demo-App im Browser

CRUD Anwendung

Wir werden unsere Demo Anwendung nun so umbauen, dass sie zu einer Todo Anwendung wird (der Klassiker nach “Hello World!”) und die eingegebenen Todos aber auch gespeichert werden.

Wir können nun alles entfernen was in der “demo.html” im Body-Tag steht.
Außerdem alles entfernen, was in der “demo.js” in den “isClient”- und “isServer”-Blöcken steht.

Jetzt kommt folgender Code in die HTML-Datei:

<head>
    <title>Demo - Todos</title>
</head>
<body>
    <h1>Todos!</h1>

    {{> todoForm}}

    {{> todos}}
</body>

<template name="todoForm">
    <fieldset>
        <input type="text" id="todo" name="todo" placeholder="What needs to be done?"/>
        <button>Add</button>
    </fieldset>
</template>

<template name="todos">
    <ul>
    {{#each todos}}
        <li>{{text}}</li>
    {{/each}}
    </ul>
</template>

Und folgender Code in die JS-Datei:

/** Client code */
if (Meteor.isClient) {
    Template.todos.helpers({
        todos: [
            { text: 'first' },
            { text: 'second' },
            { text: 'third' }
        ]
    });
}

/** Server code */
if (Meteor.isServer) {
}

Beim neuerlichen Aufruf der Seite sieht man jetzt, dass die Todos die wir in der JS-Datei eingetragen haben ausgegeben werden.

Als nächstes kümmern wir uns um die Persistenz der Daten. Dies geschieht in Meteor durch Collections (MongoDB), auf die sowohl vom Server als auch vom Client aus zugegriffen werden kann. Deshalb erstellen wir mit `Todos = new Mongo.Collection(‘todos’)` eine Collection bzw. laden diese, wenn sie vorhanden ist.
Wir fügen dann im Client-Block ein Event hinzu, dass beim klicken des Buttons ausgelöst wird. Da unter anderem jQuery von Haus aus mitgeliefert wird können wir es im Client-Block verwenden und die Eingabe mit `$(‘#todo’).val()` vom Frontend holen. Diese wird dann mit `Todos.insert({});` gespeichert und danach das Textfeld wieder geleert.
Jetzt kommt noch beim Template “todos” eine neue Helper-Funktion hinzu, die einfach alle Werte aus der Collection ausliest, absteiend sortiert und zurück gibt. Mehr ist auch nicht notwendig um Werte zu speichern und auszulesen und das ganze auch noch in Real-Time. Das heißt, wenn man einen zweiten Browser öffnet und ein Todo einträgt, sieht man im anderen Browser die Änderungen live. Leiwand.

Da wir jetzt die Daten gespeichert haben, fügen wir nun eine Checkbox und einen Löschen-Link hinzu. Jeder Eintrag in einer Collection hat auch ein Id, die wir für ein Label verwenden.

In der JS-Datei fügen wir jetzt Event-Listener für das “todos” Template hinzu. Einen beim Klick auf eine Checkbox und einen beim Klick auf den Löschen Link. Mit `todos.update()` bzw. `todos.remove();` werden Todos aktualisiert oder gelöscht. Da MongoDB eine NoSQL Datenbank ist, ist es auch nicht notwendig, dass es das Feld “checked” schon vorher gibt, man kann es einfach hinzufügen, wenn man es braucht.

Die fertige CRUD-Anwendung (Todos).

Die fertige CRUD-Anwendung (Todos).

Der vollständige Code findet sich am GitLab der FH.

HTML Code:

<head>
    <title>Demo - Todos</title>
</head>
<body>
    <h1>Todos!</h1>

    {{> todoForm}}

    {{> todos}}
</body>

<template name="todoForm">
    <fieldset>
        <legend>Add Todo</legend>
        <input type="text" id="todo" name="todo" placeholder="What needs to be done?"/>
        <button>Add</button>
    </fieldset>
</template>

<template name="todos">
    <ul>
    {{#each todos}}
        <li>
            <input type="checkbox" id="{{_id}}" checked="{{checked}}" class="chk" />
            <label for="{{_id}}" class="{{#if checked}} checked {{/if}}">{{text}}</label>
        </li>
    {{/each}}
    </ul>
</template>

JavaScript Code:

/** Create or get collection "todos" */
Todos = new Mongo.Collection('todos');

/** Client code */
if (Meteor.isClient) {
    Template.todos.helpers({
        todos: function() {
            return Todos.find(
                {},
                { sort: {createdAt: -1} }
            );
        }
    });

    Template.todoForm.events({
        'click button': function() {
            var todo = $('#todo').val();

            Todos.insert({
                text:      todo,
                createdAt: new Date()
            });

            $('#todo').val('');

            /** Prevent default form submit */
            return false;
        }
    });
}

/** Server code */
if (Meteor.isServer) {
}

Ordnerstuktur

Ein bisschen Ordnung muss sein. Meteor empfiehlt folgende Ordnerstuktur

  • /client: Alle Dateien die dem Client dienen (HTML, CSS, UI-basiertes JS)
  • /server: Dateien die nur am Server verwendet werden und nicht für den Client sichtbar sein soll
  • /public: Für Assets, Dateien in diesem Ordner können zum Beispiel mit <img src=”/filename.end” /> referenziert werden
  • /private: Dateien die nur vom Server referenziert werden können (Assets API)

Wenn man seinen Dateien in “client” und “server” Ordner aufteilt, kann man dann auch die Server- bzw. Client-Blocks in den JS-Dateien weg lassen. Gemeinsam verwendeter Code (z.B. Initialisierung von MongoDB) kann man in einen Ordner “lib” geben. Es funktioniert aber auch, wenn man sie einfach im Hauptverzeichnis als z.B. “app.js” anlegt. Heißt eine Datei “main.*” dann wird diese als letztes ausgeführt.

"main.js" Datei, in der linken Spalte sieht man die Ordernstruktur

“main.js” Datei, in der linken Spalte sieht man die Ordernstruktur

Deployment

Da auch am Server Meteor notwendig ist und man diese Voraussetzungen, gerade bei kleineren Projekten, nicht immer möglich ist, kann man seine Applikation auch kostenlos auf die Server von Meteor deployen, sofern der gewählte Name noch frei ist.

# meteor deploy appname.meteor.com

Um die App wieder zu löschen, ist folgender Befehl notwendig:

# meteor deploy --delete appname.meteor.com

Meteor ermöglicht es auch die Anwendung in eine App umzuwandeln. Um dies zu bewerkstelligen wird im Hintergrund Cordova/Phonegap verwendet. Es können also Cordova Plugins verwendet werden. Das funktioniert im Moment für iOS und Android. Für Android sind folgenden Befehlen notwendig:

# meteor install-sdk android   # SDK installieren
# meteor add-platform android  # Android als Plattform der App hinzufügen
# meteor run android           # Im Simulator starten, oder:
# meteor run android-device    # Auf Gerät starten

Durch eine “mobile-config.js” können auch noch Dinge wie App-Icon, Splashscreen, etc. festgelegt werden. Für iOS ist dementsprechend ein Mac, Xcode und Developer-Account notwendig.

Beispiele

Wer noch mehr Beispiele sehen will kann mit

# meteor create --example todos
# meteor create --example localmarket

zwei weitere Beispiele installieren.

Fazit

Meteor ermöglicht es schnell und einfach Webanwendungen zu erstellen und das auch noch mit wenig Code. Die Einarbeitungszeit ist gering und auch die Dokumentation ist gut. Außerdem gibt es schon eine große Community, mit vielen Tipps und Best Practices.
Sogar Einsteiger können ihre Anwendung leicht deployen, da Meteor eine fertige Umgebung dafür bietet und so lassen sich Projekte ohne großen Aufwand veröffentlichen.
Dieser Artikel geht nicht auf die Sicherheit von Anwendungen mit Meteor ein, hier gibt es sicher auch noch einiges was man beachten muss (Welcher Code am Server/Client?).
Die Plattform sieht vielversprechend aus, dennoch: Ob Meteor richtig einschlägt, wird sich noch zeigen.

Quellen und Links

The comments are closed.