JavaScript Tools

Inhaltsverzeichnis

Vorwort

1. Warum JavaScript?

2. Zum Aufbau des Buches

2.1. Das Beispiel

3. Das github Repository

4. Dank

1. Node.js

1.1. Die Geschichte von Node.js

1.2. Installation

1.3. JavaScript ausführen

1.4. Interaktives JavaScript

1.5. JavaScript debuggen

2. npm

2.1. Installation von Paketen

2.2. Neue Pakete finden

2.3. Eine ganz einfache Installation

2.4. Obligatorische Einträge in der Datei package.json

2.5. Optionale Einträge in der Datei package.json

2.6. Abhängigkeiten

2.7. Abhängigkeiten festschreiben

2.8. Installation der Abhängigkeiten aus package.json

2.9. Aktualisieren der Abhängigkeiten

2.10. Überflüssige Abhängigkeiten

3. Code-Check mit JSHint

3.1. JSHint oder jslint?

3.2. Der erste Einsatz

3.3. Allgemeine JSHint-Optionen

3.4. Die Ausgabe von JSHint

3.5. Umgang mit der JSHint-Ausgabe

3.6. Variablendeklaration

3.7. Spielregeln

3.8. Eine Konfigurationsdatei für JSHint

3.9. JavaScript Code Style

4. Build-Automation mit Grunt

4.1. Grunt oder gulp?

4.2. Installation von Grunt

4.3. Gruntfile.js – das Herzstück der Build-Automation

4.4. Die erste Grunt-Aufgabe

4.5. Der erste Grunt-Lauf

4.6. Grunt Watch

4.7. Grunt Templates

5. Unit-Testing mit Mocha

5.1. Installation von Mocha

5.2. Die ersten Tests

5.3. Mocha Varianten bei der Test-Suite-Definition

5.4. Mocha beeinflussen

5.5. Mocha via Grunt

5.6. JSHint für den Test-Code

6. Spione und Attrappen

6.1. Ein erster Test für das neue Modul

6.2. Ein Modul im Test ersetzen

6.3. Abhängigkeiten mit rewire ersetzen

6.4. Die notwendigen Pakete installieren

6.5. Eine API im Test simulieren

6.6. Aufrufe der API im Test überprüfen

6.7. Den letzten Fehler korrigieren

7. Die Bibliothek unter Node.js nutzen

7.1. Die Schnittstelle zur Kommandozeile

7.2. Die ausführbare Datei

8. Karma

8.1. Die Installation

8.2. Die Konfiguration erstellen lassen

8.3. Der Inhalt der Konfigurationsdatei

8.4. Karma und webpack

8.5. rewire unter webpack

8.6. Sinon.JS unter webpack

8.7. Karma mit Grunt verheiraten

9. Die Bibliothek im Browser

9.1. AngularJS installieren

9.2. HTML und JavaScript verknüpfen

9.3. grunt-webpack konfigurieren

I. Anhang

A. Details der JSHint-Konfiguration

A.1. JSHint aktualisieren

A.2. Die Optionen von JSHint 2.6.0

A.2.1. Die verstärkenden Optionen

A.2.2. Die lockernden Optionen

B. Stil-Prüfung mit jscs

B.1. Die Installation von jscs

B.2. Die erste jscs-Prüfung

B.3. jscs Regelsätze

B.4. Die Konfiguration von jscs

B.5. Weitere Optionen von jscs

B.6. jscs via Grunt

C. Eine Entwicklungsumgebung für alle JavaScript-Projekte

C.1. Ein Applikationstyp?

C.2. Modularisierung

C.3. Alternativen zur Modularisierung

Index

Gunnar Wrobel

JavaScript Tools

Besserer Code durch eine professionelle Programmierumgebung

Open Source Press

Alle in diesem Buch enthaltenen Programme, Darstellungen und Informationen wurden nach bestem Wissen erstellt. Dennoch sind Fehler nicht ganz auszuschließen. Aus diesem Grunde sind die in dem vorliegenden Buch enthaltenen Informationen mit keiner Verpflichtung oder Garantie irgendeiner Art verbunden. Autor(en), Herausgeber, Übersetzer und Verlag übernehmen infolgedessen keine Verantwortung und werden keine daraus folgende Haftung übernehmen, die auf irgendeine Art aus der Benutzung dieser Informationen – oder Teilen davon – entsteht, auch nicht für die Verletzung von Patentrechten, die daraus resultieren können. Ebensowenig übernehmen Autor(en) und Verlag die Gewähr dafür, dass die beschriebenen Verfahren usw. frei von Schutzrechten Dritter sind.

Die in diesem Werk wiedergegebenen Gebrauchsnamen, Handelsnamen, Warenbezeichnungen usw. werden ohne Gewährleistung der freien Verwendbarkeit benutzt und können auch ohne besondere Kennzeichnung eingetragene Marken oder Warenzeichen sein und als solche den gesetzlichen Bestimmungen unterliegen.

Dieses Werk ist urheberrechtlich geschützt. Alle Rechte, auch die der Übersetzung, des Nachdrucks und der Vervielfältigung des Buches – oder Teilen daraus – vorbehalten. Kein Teil des Werkes darf ohne schriftliche Genehmigung des Verlags in irgendeiner Form (Druck, Fotokopie, Mikrofilm oder einem anderen Verfahren), auch nicht für Zwecke der Unterrichtsgestaltung, reproduziert oder unter Verwendung elektronischer Systeme verarbeitet, vervielfältigt oder verbreitet werden.

Bibliografische Information der Deutschen Nationalbibliothek

Die Deutsche Nationalbibliothek verzeichnet diese Publikation in der Deutschen Nationalbibliografie; detaillierte bibliografische Daten sind im Internet über http://dnb.d-nb.de abrufbar.

Copyright © 2015 Open Source Press GmbH

Gesamtlektorat: Dr.. Markus Wirtz

Satz: textovia web application (textovia.com)

Umschlaggestaltung: Lena Levitina

Gesamtherstellung: Kösel, Krugzell

ISBN: 9783955391171 (E-Book EPUB) http://www.opensourcepress.de

Vorwort

Als ich vor einiger Zeit die Aufgabe erhielt, an einem komplexeren JavaScript-Projekt mitzuarbeiten, fehlte mir die Dokumentation für eine geeignete JavaScript-Entwicklungsumgebung. Viele der im Folgenden beschriebenen Werkzeuge wollten erst ausgesucht, verstanden und getestet werden, um zu einer produktiven Arbeitsumgebung zu gelangen.

Genau hier setzt dieses Buch an: Anhand eines zunehmend komplexeren Beispiels bauen wir eine vollständige Entwicklungsumgebung auf.

Folglich werden Sie die Lektüre nur eingeschränkt genießen, sofern keine JavaScript-Kenntnisse vorhanden sind. Der Umgang mit der Kommandozeile sollte Ihnen ebenfalls vertraut sein, denn alle beschriebenen Werkzeuge lassen sich darüber schnell und einfach ansprechen. Ein spezieller Editor wird nicht vorausgesetzt, aber zumindest die Integration mit JSHint oder jslint ist beim Schreiben von JavaScript-Code sehr hilfreich. Ich selbst nutze Emacs, und mir genügen dessen JSHint-Integration und das Syntax-Highlighting.

Neben diesen überschaubaren technischen Voraussetzungen gilt: Das Buch wendet sich an Entwicklerinnen und Entwickler, die ihre Software testgetrieben entwickeln oder doch zumindest mit zahlreichen Tests versehen. Es bietet einen guten Überblick, wie Sie Ihren Code von Beginn an auf Qualität prüfen und wie Sie die Tests sowohl unter Node.js als auch in verschiedenen Browsern laufen lassen.

Damit ist die Grundlage für eine professionelle Softwareentwicklung gelegt, wie sie auch bei anderen Sprachen selbstverständlich ist.

1. Warum JavaScript?

JavaScript hat eine eher ungewöhnliche Geschichte: Die Sprache entstand 1994 und kam lange Zeit nur im Browser zum Einsatz. Sie hielt mit der rasanten Entwicklung des World Wide Web Schritt und ist aus modernen Webseiten oder Webapplikationen nicht mehr wegzudenken. Andere Ansätze, Webseiten dynamisch zu gestalten – seien es eingebundene Java-Plugins oder Flash-Seiten – sind mittlerweile obsolet oder zumindest auf dem Rückzug. HTML5, CSS3 und JavaScript erlauben es, Webseiten zu gestalten, die in Sachen Funktionalität und Bedienung nah an Desktop-Applikationen herankommen.

Zugleich war der Werkzeugkasten der JavaScript-Entwicklung lange Zeit recht dürftig ausgestattet. In vielen anderen Sprachen gehörten Style-Checks, Code-Analysen und Unit-Testing von Anfang an zum Repertoire. Der JavaScript Style-Checker jslint wurde im Jahr 2002 veröffentlicht, acht Jahre nach der Geburt der Sprache, und ein Buch zur testgetriebenen JavaScript-Entwicklung erschien erst 2010.[1]

Die Fokussierung auf den Browser und die Tatsache, dass JavaScript-Dateien nur selten sehr groß wurden, sind naheliegende Erklärungen. Aber das World Wide Web erfasste immer größere Bereiche, und die JavaScript-Spezifikation wuchs mit; immer mehr Webseiten nutzen das zur Verfügung stehende Toolset, und es entstehen immer komplexere Webanwendungen.

Kaum ein Nutzer kommt heute noch auf die Idee, JavaScript im Browser zu deaktivieren – was früher aus Sicherheitsgründen gerne empfohlen wurde. Viele große Webseiten funktionieren ohne JavaScript gar nicht mehr.

Mit den zunehmenden Anforderungen wächst auch die Code-Basis und damit der Bedarf an Entwicklungswerkzeugen zur Code-Analyse oder zum Unit-Testing.

Node.js ermöglichte den nächsten großen Schritt. Zwar gibt es Alternativen, die JavaScript serverseitig implementieren und schon länger existieren, aber keine hat die JavaScript-Welt so nachhaltig verändert wie Node.js. In nur drei Jahren sind zahlreiche Node.js-basierte Werkzeuge entstanden, die die professionelle JavaScript-Entwicklung unterstützen. Gleichzeitig lässt sich mit Hilfe von Node.js ein Webserver betreiben, so dass man auch den Backend-Teil einer Applikation in JavaScript schreiben kann.

Damit empfiehlt sich JavaScript plötzlich in einem deutlich umfassenderen Kontext: Im Frontend ohnehin Standard, ist es nun auch Grundlage des Backend. Warum in unterschiedlichen Sprachen und Entwicklungsumgebungen arbeiten, wenn es nicht unbedingt notwendig ist?

Der JavaScript-Boom der vergangenen Jahre hat also handfeste technische Gründe, und es ist Ziel dieses Buches, zur weiteren Professionalisierung der JavaScript-Programmierung beizutragen.

JavaScript durch Node.js wie auch im Browser interpretieren zu lassen, stellt unsere geplante Entwicklungsumgebung aber vor ein Problem: Müssen es nicht eigentlich zwei Entwicklungsumgebungen sein? Kommen je nach Laufzeitumgebung nicht ganz unterschiedliche Werkzeuge zum Einsatz? Nicht zwingend, und darum setzen wir in diesem Buch auf eine Entwicklungsumgebung mit nur einem Set an Werkzeugen. Ob der auf dieser Basis entwicklte Code unter Node.js, im Browser oder in beiden Laufzeitumgebungen laufen soll, spielt keine Rolle, so dass sich der Aufwand beim Setup neuer Projekte deutlich reduziert.

Die hier beschriebene Entwicklungsumgebung setzt sich aus Werkzeugen zusammen, die über ein breites Spektrum von Projekten sinnvoll einsetzbar sind. Darüber hinaus sind sie frei verfügbar, besitzen eine aktive Community und sind unkompliziert in der Handhabung. In den jeweiligen Kapiteln sind die Gründe für die Auswahl des ein oder anderen Tools beschrieben, was – je nach Konkurrenz – mal einfacher, mal schwieriger ist.

2. Zum Aufbau des Buches

Obligatorisch für die JavaScript-Entwicklung ist mindestens ein Sprach-Interpreter. Bei den meisten anderen Programmiersprachen gibt es in diesem Punkt wenig Auswahl: den einen Compiler oder Interpreter, den die Sprache mitliefert. Für JavaScript wäre das, historisch betrachtet, der Interpreter im Netscape Navigator – allgemeiner gefasst: JavaScript-Interpreter innerhalb der Browser. Für die professionelle Softwareentwicklung ist das aber keine Lösung, denn Browser sind primär für die Anzeige gedacht und taugen kaum als IDE bzw. Texteditor.

Üblicherweise schreiben Entwicklerinnen und Entwickler ihren Code in spezialisierten IDEs, die nicht einmal an eine Sprache gebunden sind, sondern über Plugins mit dem jeweiligen Sprach-Interpreter oder Compiler kommunizieren. Diese Aufteilung hat sich in der professionellen Entwicklung bewährt. Für JavaScript bleibt damit genau eine Option, denn aktuell unterstützt nur Node.js dieses Setup effektiv.

Kapitel 1 und Kapitel 2 widmen sich darum eben dieser Basis und geben einen Überblick über Node.js und npm, das Werkzeug, mit dem Sie weitere Arbeitsmittel installieren. Wer sich schon mit beiden Tools gut auskennt, kann diese Kapitel überspringen.

JavaScript hat eine sehr lockere Sprachdefinition, und entsprechend schnell schleichen sich Fehler ein. Glücklicherweise lassen sich viele sehr einfach und sehr früh abfangen. Den dafür notwendigen Syntax-Checker beschreibt Kapitel 3; er ist für die JavaScript-Entwicklung essentiell.

Die Entwicklungsumgebung wird in Kapitel 4 um ein Build-System erweitert. Es kümmert sich darum, sämtliche Werkzeuge in einer einheitlichen API zusammenzufassen. So lassen sich alle in diesem Buch behandelten Tools über einen einfachen Satz an Befehlen über die Kommandozeile ausführen.

Das zweite wichtige Verfahren zur Qualitätssicherung neben JSHint sind automatisierte Tests, gerade bei der JavaScript-Programmierung kein einfaches Thema; schließlich gibt es mit den Browsern und Node.js zwei grundverschiedene Laufzeitumgebungen.

Je nach Projekt sind die Anforderungen an Tests sehr unterschiedlich. Kapitel 5, Kapitel 6 und Kapitel 8 versuchen den Spagat und bauen mit Mocha und Karma ein Test-Setup auf, das Code sowohl unter Node.js als auch im Browser einwandfrei testet. Das resultierende Test-Framework können Sie in jedem beliebigen JavaScript-Projekt einsetzen.

Schließlich muss es für Projekte, in denen Code für den Browser geschrieben wird, auch noch ein Werkzeug geben, das den JavaScript-Code z. B. durch Konkatenieren und Minifizieren für den Einsatz im Browser vorbereitet. Kapitel 9 kümmert sich um diesen Arbeitsschritt.

In Anhang A finden Sie eine Übersicht über sämtliche JSHint-Optionen und -Fehlermeldungen. Sie dient als Referenz und erste Anlaufstelle bei Fehlern während des JSHint-Laufs.

Als „Zugabe“ beschreibt Anhang B den JavaScript Style-Checker jscs, der für die Entwicklung nicht essentiell ist. jscs überwacht einen Satz stilistischer Regeln, sozusagen die Schönschrift beim Programmieren. Gerade in größeren Teams zahlt sich der Einsatz von jscs aber schnell aus.

Anhang C nimmt sich abschließend die Zeit, die Auswahl der Werkzeuge aus der zweiten Hälfte des Buches näher zu beleuchten. Diese eher theoretische Betrachtung ist etwas umfangreicher und hätte den Fluss der praxisorientierten Kapitel gestört. Es gibt aber sicher Kolleginnen und Kollegen, die in diesem Buch Beschreibungen von Werkzeugen wie Browserify, AMD, nodeunit und anderen erwarten; diesen möchte ich erklären, warum das Ziel – eine Entwicklungsumgebung für beide JavaScript-Laufzeitumgebungen – genau die hier beschriebene Auswahl bedingt.

2.1. Das Beispiel

Um mit JavaScript nicht „auf dem Trockenen“ zu entwickeln, bauen die Kapitel dieses Buches Stück für Stück reale Funktionalität auf. Ziel ist eine kleine Anwendung, die den Nutzer an Geburtstage erinnert. Das Resultat ist sicher nicht dazu angetan, Begeisterungsstürme zu entfachen, aber es bietet einen überschaubaren Kontext mit praxisrelevanten Anforderungen an die Entwicklung.

Am Ende steht eine Applikation, die sowohl im Browser als auch unter Node.js funktioniert und deren sauberer Code eine gute Testabdeckung aufweist.

3. Das github Repository

Seit der Veröffentlichung von Node.js legt die JavaScript-Community ein rasantes Tempo bei der Entwicklung neuer Werkzeuge vor. Wöchentlich gesellen sich neue hinzu, und die bereits veröffentlichten erfahren Erweiterungen und Verbesserungen.

Das gibt Entwicklern immer neue Features an die Hand, andererseits ist nicht ausgeschlossen, dass nach einer Aktualisierung plötzlich obskure Fehler auftreten, weil sich ein Projekt weiterentwickelt, ein anderes aber noch nicht darauf eingestellt hat.

Wir versuchen dieses Problem in den folgenden Kapiteln zu vermeiden, indem wir die zu verwendenden Versionen festschreiben. Dennoch ist – aufgrund der Arbeitsweise von npm – nicht auszuschließen, dass im Ablauf der Beispiele in einem halben Jahr ein Fehler auftritt.

Darum haben wir ein github-Repository aufgesetzt,[2] in dem Sie alle Code-Beispiele dieses Buches finden. Der master-Branch enthält nur eine README-Datei, die Aufbau und Verwendung des Repositorys beschreibt.

Natürlich darf das Repository auch gerne geklont werden, um Tipparbeit zu sparen und jederzeit an einen beliebigen Punkt im Buch zu springen, die angegebenen Beispiele auszuprobieren.

Und natürlich freue ich mich, wenn Sie – sollte sich ein Fehler finden – den zum Repository gehörigen Bugtracker nutzen, um mir das Problem mitzuteilen.

4. Dank

Bedanken möchte ich mich bei den Menschen, die mich zur Arbeit an diesem Buch ermutigt und die auf ganz unterschiedliche Weise Anteil an seinem Erscheinen haben.

Das erste Dankeswort gilt Michael Draws. Ohne ihn und einen feucht-fröhlichen Abend auf einem Berliner Weihnachtsmarkt wäre das Buch nicht entstanden.

Beträchtliche Arbeit mit diesem Buch hatte Markus Wirtz, dem ich für das hervorragende Lektorat und auch dafür danken möchte, dass er dem Projekt ohne weiteres Zögern zugestimmt hat. Vielen Dank auch an seine Mitstreiterin, Gerlinde Regensburger, die für die bessere Lesbarkeit und das Finetuning gesorgt hat.

Großen Anteil an der inhaltlichen Konzeption hat mein Kollege und Tischnachbar Franz Antesberger. Er hat nicht nur unermüdlich mit mir am Aufbau der hier beschriebenen Build-Chain gearbeitet, sondern auch bereitwillig in zahllosen Diskussionen Wissen geteilt und die Rohfassung dieses Buches überarbeitet. Ihm möchte ich ganz herzlich für die wunderbare Unterstützung danken.

Dank auch an Ingo Reinhard und Hape Zerres, zwei Kollegen, mit denen ich immer noch gerne in einem Team arbeiten würde. Beide haben sich ebenfalls durch die Rohfassung dieses Buches gequält und mit wertvoller Kritik zum Gelingen des Projekts beigetragen.

Außerdem möchte ich Matthias Bärwolff, Björn Dannemann, Tobias Deekens, Sven-Olaf Ehmann, Matthias Erche, Sebastian Misch, Stefan Schubert-Peters, Daniel Stepper und Achim Rippegather für zahlreiche Diskussionen im Team und den Aufbau einer Entwicklungsumgebung, die weit über das hier beschriebene Setup hinausgeht, danken. Euer Elan und Eure Begeisterungsfähigkeit haben mir in den letzten Monaten sehr imponiert.

Und natürlich danke ich der E-Post Development GmbH, denn ohne die Aufgabe, die Ende-zu-Ende-Verschlüsselung für den E-POSTBRIEF zu entwickeln, hätte es wohl kaum einen Grund gegeben, sich derart intensiv mit der JavaScript-Entwicklungsumgebung zu beschäftigen.

Zu guter Letzt gilt mein Dank den drei Menschen, die den größten Platz in meinem Herzen einnehmen. Ohne Euch würde gar nichts gehen.

Gunnar Wrobel, Januar 2015

[1] Christian Johansen, „Test-Driven JavaScript Development“, Addison-Wesley Professional, 2010.

[2] https://github.com/wrobel/geburtstage

Kapitel 1. Node.js

Beginnen wir in der Tradition „klassischer“ Einführungen in Programmiersprachen mit folgender Code-Zeile:

console.log('Hello world!')

Die durch console.log() erzeugte Ausgabe Hello world! passt nicht zu unserem Geburtstagsthema, so dass wir sie ein wenig abwandeln:

console.log('Gunnar Wrobel hat heute Geburtstag. Kaufe ein Geschenk!')

Die Zeile verwendet die Funktion console.log(), der wir eine Zeichenkette zur Ausgabe übergeben. Natürlich erfolgt die Ausgabe nicht, solange diese JavaScript-Zeile nicht interpretiert wird.

Der Browser ist für die schnelle Interpretation von JavaScript nicht mehr zeitgemäß. Als Werkzeug auf der Kommandozeile ist Node.js die deutlich bessere Wahl, weshalb wir es als Grundlage der hier aufzubauenden Entwicklungsumgebung nutzen. Aber was ist dieses recht junge Node.js überhaupt, und wie lässt es sich im System installieren?

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!