Automatisch, praktisch, gut

Integration von JavaScript-Tools in bestehende Prozesse
Kommentare

Der Trend zu Anwendungen auf Basis von HTML und JavaScript ist unverkennbar. Er zeigt sich an der Verfügbarkeit mobiler Geräte mit Browsern und den gestiegenen Anforderungen an Webanwendungen. Für den täglichen Einsatz der Programmiersprache, gerade in größeren Projekten, ist eine gute Integration von Tools in den Prozess unabdingbar – ein Luxus, an den sich Java-Entwickler inzwischen gewöhnt haben und der bewirkt, dass viele Schritte im Entwicklungsprozess automatisiert sind. Denn bei der Verwendung einer Programmiersprache ist der Funktionsumfang nur die halbe Miete. Erfahren Sie, wie die Programmiersprache JavaScript in einen bereits bestehenden Prozess integriert werden kann.

Dass die Automatisierung von Schritten im Entwicklungsprozess wirklich ein Luxus ist, wird einem Entwickler erst bewusst, wenn er diese aufgrund fehlender Toolunterstützung wieder manuell durchführen muss (z. B. durch das fehlende Wissen über Tools beim Einstieg in eine neue Programmiersprache). Bei der Entwicklung von Java setzt der Entwickler in Eclipse eine Anforderung um und checkt sie ins Versionskontrollsystem ein. Auf Jenkins wird mithilfe von Maven eine neue Version gebaut, getestet und ausgerollt. Für Java gibt es von der Entwicklungsumgebung bis hin zur Auslieferung eine hochwertige und etablierte Tool-unterstützung. Egal ob Eclipse, NetBeans oder IntelliJ IDEA, egal ob JUnit oder SeleniumHQ, egal ob SVN oder Git, egal ob Maven, Gradle oder Ant, egal ob Hudson oder Jenkins, egal ob JavaDoc oder Doxygen – für all diese Schritte gibt es im Java-Umfeld gute Tools, die in der Entwicklergemeinde weit verbreitet sind. Doch wie sieht das im JavaScript-Umfeld aus? Eine Frage, die sich gerade Entwickler stellen, die vorher Java entwickelt haben und jetzt in JavaScript einsteigen.

Auch wenn jeder Entwickler JavaScript-Code lesen, verstehen und anpassen können sollte, ist gerade der Anfang nicht leicht. Hinzu kommt, dass Wissen über die Tools und ihre Integration in den Entwicklungsprozess fehlt. Im Folgenden soll dies alles beleuchtet und ein Überblick über verwendbare Tools gegeben werden – mit klarem Fokus auf Java-Entwickler. Das Ziel ist es, für jeden Prozessschritt Tools zu beschreiben, damit der aus dem Java-Umfeld bekannte Prozess auch auf JavaScript-Code anwendbar ist. Dabei soll der Einstieg so sanft wie möglich erfolgen.

Es wird hier von einem typischen Prozess ausgegangen. Dieser besteht aus den Schritten Entwickeln, Bauen (Validieren, Testen, Paketieren) und Dokumentieren. Können diese Basisschritte zuverlässig und konstant ausgeführt werden, kann der Prozess um weitere Maßnahmen wie  (automatisches) Deployment erweitert werden. Sie bleiben bis dahin erst einmal außen vor. Für jeden Schritt sind andere Tools notwendig.

Abb. 1: Prozessschritte beim Einsatz von JavaScript

Entwickeln

Die gewohnten Java-Entwicklungsumgebungen wie Eclipse, NetBeans IDE oder IntelliJ IDEA bieten viele Funktionen. Auch wenn davon nicht alle benötigt werden, so gibt es doch einige Must-have-Funktionen, die auch für die JavaScript-Entwicklung zur Verfügung stehen sollten:

  • Syntax-Highlighting und Codeformatierung
  • Codenavigation und Code Completion
  • Refactoring
  • Debugging

JavaScript-Code kann auch mit den gewohnten Java-Entwicklungsumgebungen geschrieben werden. Sind die Funktionen nicht ausreichend, können die Entwicklungsumgebungen durch Plug-ins wie Aptana [1] erweitert werden. Alternativ zur gewohnten Java-IDE gibt es spezialisierte Entwicklungsumgebungen, die komplett auf JavaScript ausgerichtet sind. Dazu zählen JetBrains WebStorm [2] und Aptana Studio [3]. Dabei handelt es sich um Fat-Client-Entwicklungsumgebungen, im Gegensatz zu Umgebungen, die im Browser und der Cloud laufen. Die komplett im Browser laufenden Entwicklungsumgebungen muten im ersten Moment etwas ungewohnt an, bieten aber auch gewisse Vorteile. Cloud9 IDE [4], Brackets [5] und Orion [6] sind Vertreter dieser Art. Beworben werden sie mit Vorteilen wie direkter Verfügbarkeit und einer möglichen Zusammenarbeit mit Kollegen.

Die grundlegendsten Anforderungen an eine Entwicklungsumgebung – wie Syntax-Highlighting und Codeformatierung – werden von allen aufgeführten Entwicklungsumgebungen erfüllt. Anders sieht es bei etwas anspruchsvolleren Funktionen wie Codenavigation und Code Completion aus. Unter Codenavigation ist die Möglichkeit zu verstehen, z. B. eine JavaScript-Funktion zu markieren und zu deren Implementierung zu springen (zu navigieren). Das funktioniert nur, wenn der Code erfolgreich geparst und die Einzelteile des geparsten Codes von der Entwicklungsumgebung korrekt verstanden wurden. Deshalb ist das auch die Voraussetzung für Code Completion. Hier profitieren ganz klar die Entwicklungsumgebungen wie Eclipse und JetBrains WebStorm. Da es diese Umgebungen auch für andere Programmiersprachen gibt, besitzen sie entsprechende Funktionalitäten dafür. Für die alltägliche Arbeit ebenfalls wichtig ist tool-unterstütztes Refactoring. Dass damit mehr als „Suchen und Ersetzen“ gemeint ist, sollte an dieser Stelle klar sein. Leider können das nicht alle der aufgeführten Entwicklungsumgebungen. Gerade die neuen, schlanken, browserbasierten Entwicklungsumgebungen tun sich damit (noch) schwer. Diese fundamentalen Basics müssen aber gegeben sein, um halbwegs effizient entwickeln zu können.

Neben dem reinen Entwickeln und Schreiben des Codes soll die Entwicklungsumgebung auch das Ausführen und ganz besonders das Debuggen des Codes anbieten. Gerade beim Debugging unterscheiden sich die Entwicklungsumgebungen: Nur wenige unterstützen Debuggen direkt aus der Entwicklungsumgebung heraus, und am ehestens funktioniert das mit WebStorm. Da der Code meist direkt im Browser ausgeführt wird, kann der aber auch sehr gut mithilfe der browsereigenen Entwicklertools debuggt werden (die bei IE und Chrome mitgelieferten Entwicklertools bzw. Firebug [7] bei Firefox).

Ist der Code der Anwendung entwickelt, wird er im Versionskontrollsystem hinterlegt. Welche Versionskontrollsysteme dafür zur Verfügung stehen, hängt von der verwendeten Entwicklungsumgebung ab. Während Eclipse viele verschiedene unterstützt, bietet etwa die Cloud9 IDE nur Git und Mercurial, teilweise begrenzt auf Hoster wie GitHub [8] oder Bitbucket [9].

Bauen

Ist die Entwicklung einer Anforderung abgeschlossen, soll die komplette Anwendung gebaut werden. Klappt dies teilweise auch noch „irgendwie so“ in der lokalen Entwicklungsumgebung, muss das Bauen der Anwendung auf dem Build-Server automatisiert möglich sein und erfolgen. Das Bauen umfasst u. a. folgende Tätigkeiten:

  • Validierung von Dateien (sowohl JavaScript als auch CSS)
  • Durchführung statischer Codeanalyse
  • Test des Codes
  • Zusammenfassen mehrerer JavaScript-Dateien zu einer auszuliefernden Datei und Verkleinerung dieser Datei (Stichwort „Minified Version“)
  • Paketierung sämtlicher Dateien für das Deployment

Build-Server wie Hudson oder Jenkins können als Standard bei der Java-Entwicklung gesehen werden. Wer darauf den Build-Prozess laufen hat, kann mit einfachen Bordmitteln JavaScript ebenfalls dort bauen lassen. Hierbei hilft das im Java-Umfeld bekannte Tool Maven [10]. Es stammt von Apache und bietet inzwischen viele zusätzliche Plug-ins, über die problemlos die genannten Anforderungen realisiert werden können. Mit Maven kommt somit ein für Java-Entwickler vertrautes Tool zum Einsatz.

Als Erstes werden die verwendeten HTML- und CSS-Dateien validiert. Die HTML- und die CSS-Dateien werden gegen den W3C-Standard (W3C-CSS-Validator für Style Sheets und W3C-HTML-Validator für HTML) geprüft. Dies erfolgt über Maven mit Maven-css-validator-plugin [11] (groupid: org.jvnet.mcvp). Neben dem Source-Verzeichnis kann angegeben werden, welche CSS-Version geprüft werden soll. Wie bei der statischen Codeanalyse kann über die Eigenschaft cssValidationFailureIgnore bestimmt werden, ob das Bauen bei einem Fehler abgebrochen werden soll.

Nachdem der Code validiert ist, wird eine statische Codeanalyse mittels JSLint [12] durchgeführt. JSLint ist ein Tool zur Bestimmung der Qualität von JavaScript-Code ähnlich Checkstyle [13], FindBugs [14] und Sonar [15] für Java. Aufgrund bestimmter Eigenschaften wie beispielsweise Globals und fehlender Typsicherheit von JavaScript ist das noch viel wichtiger als bei Java. Die Regeln für die Analyse können auf der Webseite von JSLint zusammengestellt und die Konfiguration per Copy and Paste übernommen werden. Positiver Nebeneffekt eines guten Regelsets ist, dass der Code auch einige Monate später noch gelesen werden kann, auch von Dritten. Das Ergebnis der statischen Codeanalyse ist ein Report, der die gefundenen Regelverstöße pro Funktion auflistet (Listing 1, [16]).

Listing 1
  net.alchim31.maven
  yuicompressor-maven-plugin
  
    
      
        jslint
      
    
          
  
    
      file-1.js
      
      file-n.js
    
    true
  

Hat der Code die statische Analyse passiert, werden Tests ausgeführt. Damit soll sichergestellt werden, dass die entwickelte Anwendung auch die Erwartungen erfüllt. Dazu werden auf dem Build-Server Tests automatisiert ausgeführt. Beim automatischen Testen gibt es aber einige Dinge zu beachten. Was genau und welche Testtools dafür existieren, wird im Abschnitt „Testen“ genauer erklärt.

Für die Paketierung müssen die Dateien vorbereitet werden. Dazu gehört, dass JavaScript- und CSS-Dateien zu einer einzigen Datei kombiniert werden. Dann wird diese Datei verkleinert, um später im Produktivbetrieb Bandbreite zu sparen und das Laden der Datei zu beschleunigen. Auch dieser Schritt erfolgt mit Maven. Hierzu wird maven-minify-plugin [17] (groudId: com.samaxes.maven) verwendet. Ganz wichtig ist dabei die Reihenfolge, in der die Dateien aufgelistet sind. Es kann sonst, unter anderem aufgrund der bereits angeführten globalen Variablen, zu unerwünschten und schwer nachvollziehbaren Nebeneffekten kommen (Listing 2, [18]).

Listing 2
 com.samaxes.maven minify-maven-plugin 1.5.2    minify      file-1.css  file-n.css  style.css  file-1.js  file-n.js  app.js   

Die Paketierung für das Deployment kann im Anschluss erfolgen. Je nach Server kann beispielsweise maven-war-plugin [19] (groupId: org.apache.maven.plugins) genutzt werden. Es ist dabei wichtig zu beachten, dass nur die minifizierte JavaScript- und CSS-Datei mit in das Paket aufgenommen werden.

Testen

Um bei der heutigen Softwarekomplexität Qualität zu garantieren, ist eine umfangreiche Testphase ein Muss. Entsprechende Testtools für JavaScript-Code sind JSUnit, EnhanceJS [20] und Jasmine [21]. Neben der Art des Testens (z. B. Unit-Test, Integrationstest) sind bei der Auswahl des Testtools noch andere Kriterien zu beachten. Mit am wichtigsten ist, ob die Tests manuell oder automatisiert ausgeführt werden und ob die Tests im Browser laufen sollen. Kann beispielsweise kein Browser geöffnet werden – vielleicht, weil der Build-Server keine Grafikkarte besitzt –, bleibt nur Jasmine. Die anderen beiden Tools laufen ausschließlich im Browser.

Jasmine benötigt für die Ausführung der Tests kein DOM und somit auch nicht zwangsläufig einen Browser. Das ist gerade beim automatisierten Test als Schritt des Bauens von Vorteil. Mit jasmine-maven-plugin [22] (groupId: com.github.searls) können die Tests von Maven gestartet werden. Über die beiden Parameter jsSrcDir und jsTestSrcDir wird angegeben, wo der Code der Anwendung und wo der Code der Tests liegt, ähnlich zur Aufteilung in der Java-Entwicklung. Zusätzlich kann auch die für den Test genutzte Browserversion (mit ) angegeben werden. Das Ergebnis des Tests wird von Jasmine zu einem Report aufbereitet.

Listing 3
 com.github.searls jasmine-maven-plugin 1.2.0.0    test     src/main/webapp/js  file-1.js  file-n.js  src/main/webapp/js/test INTERNET_EXPLORER_8 true  

Die hier erwähnten Tools zum Testen von JavaScript-Anwendungen haben gewisse Grenzen. Zu diesen Grenzen zählen (asynchrone) Backend-Zugriffe, Events und optische Effekte. Um diese Grenzen zu überwinden, sind weitere Tools notwendig (z. B. Mocha [23], jasmine-jquery [24], CasperJS [25] oder PhantomJS [26]).

Anstatt direkt den JavaScript-Code zu testen, kann auch die Anwendung mit Tools wie Selenium [27] getestet werden, was eher einem Oberflächentest entspricht. Wie auch Jasmine kann Selenium von Maven gestartet werden. Selenium bringt dafür entsprechende Plug-ins direkt mit [28].

Dokumentieren

Ein guter Code und lange Lebenszyklen machen die Dokumentation des Codes zur Pflicht. Die Antworten auf „Warum wurde das hier so gemacht?“ und „Was macht diese Zeile Code?“ müssen festgehalten werden. Als Java-Entwickler möchte man den Komfort von Javadoc nicht missen. Dazu gehören nicht nur das Schreiben von Kommentaren im Code, sondern auch die daraus entstehenden Dokumente.

Im Idealfall erfolgt die Dokumentation von JavaScript-Code auf die gleiche Art und Weise wie bei JavaDoc. Das heißt: Wenn möglich, sollte auf die gleiche Art und Weise dokumentiert und es sollten dieselben Tags verwendet werden können. Mögliche Frameworks sind ext-doc [29] und JSDoc Toolkit [30]. Beide Frameworks parsen den JavaScript-Code nach Kommentaren und darin enthaltenen Tags und generieren als Ergebnis eine formatierte Dokumentation. Während ext-doc rund zwanzig Tags umfasst, bietet JsDoc Toolkit fast doppelt so viele Tags. Das ist ein Nachteil unterschiedlicher Frameworks: Diese können nicht einfach ausgetauscht werden. Davon abgesehen, dass ext-doc einfach weniger Tags unterstützt als JsDoc Toolkit, werden die Tags auch unterschiedlich geschrieben. Ein Beispiel dafür ist @memberOf (JsDoc Toolkit) und @member (ext-doc).

Sowohl ext-doc als auch JsDoc Toolkit bieten die Möglichkeit, eigene Templates zu nutzen. Über die Templates kann das Aussehen der generierten Dokumentation beeinflusst werden. Sinnvollerweise sind die Templates so gestaltet, dass die generierte Dokumentation der von JavaDoc ähnelt. Das erleichtert das Lesen und Verstehen.

Die Erstellung der Dokumentation mit JsDoc Toolkit kann automatisiert werden. Dazu wird JsDoc Toolkit per Maven JSTools Plugin [31] (groupId: gr.abiss.mvn.plugins) in Maven und das Bauen integriert. Wird nach jeder Änderung gebaut, ist immer die aktuelle Dokumentation verfügbar (Listing 4, [32]).

Listing 4
    gr.abiss.mvn.plugins maven-jstools-plugin false   ${project.build.directory}/site/sarissa  **/*.js  **/*-compressed.js  true      jsdoc       
Fazit

Vor dem Einstieg in die JavaScript-Entwicklung muss sich kein Java-Entwickler scheuen. Aus der Java-Entwicklung bekannte Tools können eingesetzt werden, um auch Schritte im JavaScript-Prozess zu automatisieren. Tabelle 1 zeigt, mit welchen Tools JavaScript in die einzelnen Prozessschritte integriert werden kann.

Prozessschritt
Tool

Entwickeln

JetBrains WebStorm

Bauen

Maven

-Validieren

maven-css-validator-plugin

JSLint

-Testen

Jasmine

-Paketieren

maven-minify-plugin

maven-war-plugin

Dokumentieren

JsDoc

Tabelle 1: Passende Tools zu den Prozessschritten in JavaScript

Bei den vorgeschlagenen Tools schwingt die Annahme mit, dass es bei Anwendungen einen Teil gibt, der mit Java entwickelt werden sollte. Ist das nicht der Fall, d. h. handelt es sich um eine reine JavaScript-Entwicklung, ist es sinnvoll, Tools zu nutzen, die speziell für JavaScript ausgelegt sind. Meist haben solche Tools nicht mit den Kompromissen zu kämpfen, die bei Java-Tools nötig sind, weil sie allgemeingültig sein wollen. Als Beispiel sei an dieser Stelle Maven genannt, als Alternative kann Brunch [33] eingesetzt werden.

Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -