JavaScript – Jetzt aber!

Eindrücke vom Besuch der JavaScript-Konferenz enterJS

An JavaScript führt kein Weg vorbei, aber…

Die Zeiten, in denen JavaScript in Enterprise Entwicklungen nur dem Aufhübschen von Webseiten diente, sind natürlich längst vorbei. Auch Single-page applications (SPA) stehen nicht mehr am oberen Ende der Komplexitätsskala von JavaScript-Anwendungen  – JavaScript macht nicht im Browser-Front-End halt. Längst ist die Sprache im Backend (z.B. Node.js), in cross-platform applications (z.B. Electron), auf mobilen Endgeräten und – na klar – auch im Internet of Things zu Hause.

An JavaScript führt heute kein Weg vorbei. Wer eine Anwendung im Enterprise-Umfeld herstellen will, wird sich mit JavaScript beschäftigen müssen. Dabei machen neben der rasanten Ausbreitung der Sprache auch die Entwicklung der Sprache selbst sowie Sprachen in ihrem Umfeld, vor allem TypeScript, neugierig. Doch wie ist diese Entwicklung zu bewerten? Kann ich mit JavaScript jetzt Fullstack Enterprise Anwendungen entwickeln, weil die Sprache nun das Schreiben von wartbarem Code vereinfacht? Ist der Technologie-Stack heute so umfänglich, dass der Betrieb von JavaScript-Anwendungen damit nachhaltig möglich ist?

Eigene Erfahrungen

JavaScript ist bei meinem Dasein als Softwareentwickler ein ständiger Begleiter. Erst in Form von im Web-Frontend unstrukturiert verteilten Funktionen zur Aufwertung der User Experience einzelner GUI-Komponenten. Später mit komplexerer Logik für Workflow-basierte Dateneingaben. Dabei bin ich schnell zu der Einsicht gelangt, dass eine JavaScript-Anwendung mit großer Disziplin geschrieben werden muss, wenn man diese über einen längeren Zeitraum pflegen möchte. Hierbei ist das Buch von Douglas Crockford JavaScript: The Good Parts eine großartige Hilfe. Darin ist zu lernen, wie Strukturierung von Code und Kapselung auch mit JavaScript möglich ist.

Der Großteil meiner Erfahrung als Softwareentwickler basiert allerdings auf der Anwendung objektorientierter (OO) Sprachen, hauptsächlich Java. Vermisst man in Java heute oft umfassendere funktionale Konzepte, wie sie z.B. in Scala aber auch immer schon in JavaScript zu finden sind, vermisse ich bei JavaScript die Typsicherheit und Kapselung zur Strukturierung großer Anwendungen. Mit Disziplin und entsprechenden Patterns ist Strukturierung auch in JavaScript möglich. Allerdings reicht die Unterstützung des Entwicklers bei der Übersicht über Zusammenhänge im Code zur Compile-Zeit nie an die Mächtigkeit statisch typisierter, objektorientierter Sprachen heran.

Spätestens als ich auf einige Anwendung, die auf Electron basieren (z.B. Atom), aufmerksam geworden bin, habe ich mir allerdings die Frage gestellt: Wie sind solche großen, komplexen Anwendungen in JavaScript zu entwickeln?

Konferenzbesuch – enterJS

Eine gute Gelegenheit dieser Frage nachzugehen war der Besuch der Konferenz enterJS. Auf dieser Konferenz gab es neben einigen Vorträgen zur Sprache JavaScript selbst vor allem jede Menge Beiträge aus der Praxis. In den Vorträgen wurden unterschiedliche Aspekte beleuchtet, die mich einer Bewertung näher gebracht haben.

JavaScript – die Sprache

Wie der Beitrag von Brian Terlson zeigte, ist die Entwicklung von JavaScript bzw. des ECMA-Script Standards sehr lebhaft. Dabei werden auch immer wieder Features berücksichtigt, die die Wartbarkeit von Code verbessern und OO-Entwickler eine leichtere Orientierung geben sollen. Dazu zählt z.B. die Einführung von _Classes_. Gerade aber das Beispiel einer Class in JavaScript macht ein Dilemma deutlich. JavaScript ist eine Prototype-basierte Sprache und kennt keine Klassenvererbung. Das Prototypmodell ist ein sehr flexibles Konzept. Aber es muss diszipliniert angewendet werden, um nicht unerwartete Effekte zu erzielen. Aus meiner Sicht sind Classes vor diesem Hintergrund etwas verwirrend, da sie Klassenvererbung suggerieren. Zudem assoziiert man auch mit Klassen eher einen Typ, wie das z.B. in Java der Fall ist. In JavaScript repräsentiert eine Class aber keinen Typ. JavaScript ist eine funktionale, Prototypen-basierte Sprache im Gewand einer typischen OO-Sprache wie z.B. Java. Das kann schnell zu Missverständnissen führen. Deutlich wird das z.B.  an der Diskussion über private Properties im Zusammenhang mit dem Vorschlag zur Einführung privater Felder in ECMA-Script. Es ist zunächst nicht offensichtlich, warum ein Keyword `private` hier nicht funktioniert und stattdessen das Prefix `#` verwendet wird.

Wie mächtig das Prototypmodell ist, hat der Vortrag von Michael Wiedeking anhand des Proxy-Objektes anschaulich verdeutlicht. Die Anwendung dieses Proxy-Objektes ermöglicht sehr effizienten Code, der gerade bei der Framework-Entwicklung interessant ist. Aber auch dieses mächtige und flexible Konstrukt birgt die Gefahr, bei unvorsichtiger Verwendung sehr schwer nachvollziehbares Verhalten in eine Anwendung zu kodieren.

Frameworks, Module und npm

Die Entwicklung von Frameworks im JavaScript ist rasant. War in 2016 Angular noch ein Top-Thema auf der enterJS, wurde dieser Rang nun von React eingenommen. Viele Teilnehmer und Vortragende berichteten über das enorme Tempo, in dem neue Frameworks entstehen oder bestehende geändert werden. So waren z.B. die gravierenden Änderungen von AngularJS 1 auf Angular 2 für viele mit großen Aufwänden bei der Migration verbunden.

Bei der Verwendung von Modulen berichtete Patrick Daehter von den Herausforderungen, die bei der Vielzahl feingranularer Module im npm bestehen. Oft werden Lizenzen nicht ausreichend gepflegt, was den kommerziellen Einsatz deutlich erschwert oder unmöglich macht. Vor dem Hintergrund dieses Vortrages drängte sich mir die Frage auf, warum sich in der JavaScript-Community diese feingranularen Module etabliert haben. Mein Eindruck ist, dass hier schnell der Overhead im Dependency Management den Nutzen von sehr kleinen Modulen (z.B. isArray) übersteigt. Ich bin gespannt, ob sich künftig größere Utility Bibliotheken, wie sie im Java-Umfeld üblich sind, z.B. das Apache Commons Projekt, entwickeln.

Verwendung von JavaScript in Enterprise-Anwendungen

Bezüglich der Frage, ob auf der Konferenz Fullstack-JavaScript Unternehmensanwendungen präsentiert werden, wurde meine Skepsis bestätigt. Zumindest auf der enterJS beschränkte sich die Anwendung von JavaScript bei den präsentierten Projekten im Wesentlichen auf das GUI. Und allein dabei gibt es offensichtlich genügend Herausforderungen zu bewältigen, die von der Performance beim Laden großer GUIs bis hin zur Integration von Microservices in einem einheitlichen GUI reichten.

Vorträge zum Thema Domain Driven Design (DDD) (z.B. von Carola Lilientahl), hatten eher einführenden Charakter. Ist das (jenseits der neuen Präsenz von DDD im Gepäck von Microservices) ein Hinweis auf die erkannte Notwendigkeit größere Anwendungen mit einer geeigneten Methode modellieren zu müssen?

OK – wir machen mit!

Der Vorteil von JavaScript besteht hauptsächlich darin, dass die Sprache wirklich überall ausgeführt werden kann. Mit JavaScript lassen sich inzwischen echte cross-platform Anwendungen bauen, die im Browser, im Backend, auf dem Desktop und auf mobilen Geräten laufen. Das hat einen großen Reiz.

Der funktionale Charakter und das Prototypmodell von JavaScript ermöglichen sehr kompakten und effizienten Code. Das kann sehr schön sein, muss aber mit Hinblick auf die Nachvollziehbarkeit maßvoll eingesetzt werden. Eine sehr interessante Alternative zu JavaScript ist m.E. Lua. Diese Sprache setzt ebenfalls Prototypen-basierte Objektorientierung und funktionale Programmierung um. Hierbei gefällt mir im Vergleich zu JavaScript, dass die Sprache mit ihrer Syntax die Konzepte offensichtlich macht. Wir verwenden Lua z.B. in Rahmen unsere Dokumentation im Zertifizierungsverfahren nach Common Criteria für den Konnektor.

Vor allem mit TypeScript hat sich nicht zuletzt durch deren Verwendung in Angular eine Sprache etabliert, die viele Unzulänglichkeiten von JavaScript ausgleicht und mit der effektiv gearbeitet werden kann.

Vor diesem Hintergrund, entwickeln auch wir bei n-design Anwendungen mit JavaScript bzw. TypeScript. Das funktioniert gut und die Ergebnisse sind zufriedenstellend. Die eingangs gestellte Frage, wie der Komplexität großer Projekte heute mit JavaScript begegnet wird, konnte mein Besuch der Konferenz enterJS nicht ausreichend beantworten. Zumindest im Enterprise-Umfeld sind JavaScript-Anwendungen im Backend offenbar Mangelware. Ohne viel Disziplin und einer sehr soliden Testabdeckung können Fehler in der Entwicklung mangels Typsicherheit nicht minimiert werden. Damit verlagert sich ein Teil der Identifizierung von Fehlern von der Compile- in die Integrations-Phase. Zudem scheinen sehr viele größere Projekte eher Sprachen wie CoffeeScript oder TypeScript zu verwenden, die nach JavaScript transpilieren.

Wer auf der Suche nach einer Alternativen zu Java für die Entwicklung komplexer Enterprise-Anwendungen ist, findet mit Kotlin einen sehr spannenden Kandidaten, der z.B. deutlich bessere Unterstützung für funktionale Programmierung als Java bietet. Kapselung und ein statisches Typsystem sind auch in Kotlin, wie in Java, essentielle Features, auf die ich in großen Anwendungen nur ungerne verzichte.