JavaScript-Bibliotheken und die jüngere JavaScript-Geschichte
Mathias Schäfer (molily)
- javascript
- notizen
- selfhtml
Wie Bibliotheken neue Voraussetzungen für das Vermitteln von JavaScript schaffen
Was viele Webworker betrifft und beschäftigt, sind die in den letzten Jahren aus dem Boden geschossenen JavaScript-Frameworks wie Prototype, jQuery, Dojo und sonstige Ajax-, Interface- und Effektbibliotheken. Dieser Umbruch scheint mir in seinen Hintergründen noch nicht geklärt und die Auswirkungen noch nicht abschließend aufgearbeitet zu sein – vor allem im Hinblick auf die technische Dokumentation und Vermittlung von JavaScript: Diese neue Situation beschäftigt mich bei der Arbeit an einer kleinen Einführung in JavaScript, da sie Fragen aufwirft wie »Soll man noch JavaScript lernen oder gleich jQuery?« und »Wie hängt der Einsatz von Frameworks mit dem Lernen von JavaScript zusammen?«
Die Diskussion um die Vor- und Nachteile von JavaScript-Bibliotheken lief Ende letzten Jahres groß in der internationalen Blogosphäre. Auf der @media-Konferenz 2006 fand eine Podiumsdiskussion zum Thema Javascript Libraries: Friend or Foe? statt, die als MP3-Mitschnitt und Transkript vorliegt. Eine Übersicht über die Diskussion in Weblog-Artikeln bietet Peter-Paul Koch. Ich möchte ihr nichts substanzielles hinzufügen, sondern ein paar subjektive Notizen, lose Ideen und Beobachtungen in Sachen JavaScript-Geschichtsschreibung zusammentragen.
Wenige JavaScript-Spezialisten wie etwa die, die auf der @media-Veranstaltung diskutierten, versuchen schon seit langem, JavaScript ein positives Image zu geben und vernünftigen Gebrauch zu propagieren. Als DOM Scripting und Unobtrusive JavaScript gelang das auch im begrenzen Maße, aber wirklich ausschlaggebend für den neuerlichen Run auf JavaScript waren Ajax, die Effekte sowie der einfache Einsatz von JavaScript an sich durch Bibliotheken. Dadurch gewann JavaScript Interessenten, die mit anderen Erfahrungen und Zielen an JavaScript herantraten. Eine spannende, aber auch herausfordernde Entwicklung für diejenigen Enthusiasten, die JavaScript-Techniken und -Theorien weiterentwickeln.
Durch kinderleichte Werkzeuge wie jQuery hat JavaScript eine starke Popularisierung erlangt – viele können JavaScript einsetzen, ohne JavaScript können zu müssen. Frameworks verwirklichen den Grundsatz: »The bad news: JavaScript is broken. The good news: It can be fixed with more JavaScript.« Sie vereinheitlichen den Flickenteppich von APIs unterschiedlicher Herkunft und Machart. Sie setzen Programmiertechniken voraus, die dem gemeinen JavaScript-Programmierer vorher meist unbekannt waren.
Dieser vorgegebene Rahmen kann zu guten Resultaten verhelfen, Voraussetzung ist allerdings, dass der Anwender um die Vorteile und Hintergründe dieser Programmierweise wissen. Den Prozess vom Spaghetticode zum Framework – von der Erfindung von Helferfunktionen wie getElementsByClassName
bis hin zu $("beliebige CSS- oder XPath-Selektoren").chainability()
– lief über viele Jahre. Diese Entwicklung nachzuvollziehen wäre zum Verständnis aktueller Ansätze nötig, ist den meisten aber nicht ohne weiteres möglich, da sie nie selbst Helferfunktionen entwickelt haben, die den vorherigen Programmierstil grundlegend über den Haufen warfen.
Obgleich gibt es dutzende Helferscripte, die Schritt für Schritt optimierten Code für häufige Aufgaben ermöglichen, man denke alleine an die Veränderungen, die eine Helferfunktion wie forEach bereits mit sich bringt. Die Notwendigkeit der Abstraktion ist beim gegenwärtigen, lückenhaften und unausgereiften ECMAScript und DOM quasi genetisch veranlagt – man muss sich nur überlegen, wie man am besten hineinkommt.
Die Interna von Frameworks sind für die meisten undurchschaubare Rocket Science, ihr Code unlesbar, ihre Funktionsweise unklar, ihre Dokumentation nicht für Einsteiger geeignet. Hinter den Designentscheidungen stecken Jahre Forschung und Fachdiskussion. Heraus kommt, dass die Bibliothek auf Außenstehende nicht wie ein Baukasten, sondern wie ein monolithisches Ganzes, wie eine Black Box wirkt. Wenn sie dann noch nichtmal im Ansatz modularisierbar ist und der Anwender keinen Schimmer davon hat, welche Teile welche Funktion erfüllen und ob diese benötigt werden, heißt es leider Fressen oder Sterben. Wenn man hinter die Kulissen der API schaut, findet man ohnehin selten aufgeräumten Code, der auf Allgemeinverständlichkeit und Anpassbarkeit angelegt ist.
Ein großes Problem der Bibliotheken-Benutzung scheint mir, dass sie nicht benutzt werden: Von hunderten Features, die eine Bibliothek bietet, bleiben die meisten unbekannt. Ein paar wenige zentrale Features werden extrem häufig verwendet, die Mehrheit liegt außerhalb dieses Kreises. Schuld daran sind fehlende Tutorials und nutzlose API-Referenzen, aber auch ein falsches Verständnis von Bibliotheken als eierlegende Wollmilchsäue, Allround-Werkzeuge selbst für den unmöglichsten Fall – sie sind schlicht und einfach bloated anstatt auf das Wesentliche reduziert.
Damit einher gehen Scripte, bei denen Framework-Logik und konventionelles JavaScript vermischt werden. Rudimentäre Kenntnisse der herkömmlichen Lösungsweise vermischen sich mit rudimentären Kenntnissen des Frameworks. So kommt Code heraus, der in einer Zeile die Bibliothek nutzt und in der nächsten wieder völlig an ihr vorbeiprogrammiert. Das Kauderwelsch, das immer wieder aus der Logik des verwendeten Frameworks herausfällt und dieses überhaupt nicht ausreizt, ist inkompatibel, schwer verständlich und scheußlich wartbar.
Bei kleinen, begrenzten Helferbibliotheken (man denke an DOMAssistant, ff oder Dan Webbs Scripting Essentials) wäre dies kein großes Problem, aber es entspricht nicht dem Totalitätsanspruch derjenigen Biliotheken, die einen einheitlichen Abstraktionslayer ohne Schlupflöcher zur Verfügung stellen wollen.
Zwischen Entwicklern von Bibliotheken-Plugins sowie Fertigscripten und den JavaScript-Theoretikern scheint eine Kluft zu verlaufen. Diese drückt sich darin aus, dass deren Standardwerke oftmals nicht rezipiert wurden und beispielsweise manche populären Scripte wie Thickbox jegliche Organisation vermissen lassen. Das ist coding like 1998, nur mit jQuery im Nacken. Viele solcher Erweiterungen fallen systematisch aus der Logik des Frameworks heraus und nutzen von der 77-Kilobyte-Bibliothek nur zwei gesonderte Funktionen – dieses ein »Plugin« zu nennen, ist eine Dreistigkeit, aber durchaus an der Tagesordnung.
Wie soll diese Chose nun JavaScript-Anfängern nahegebracht werden? Seitdem es jQuery und Co. gibt, lautet die Antwort auf unzählige Anfängerfragen: Macht dir keinen Kopf und nimm gleich jQuery (oder ähnliches). Der Erfolg ist garantiert, ein tieferes Verständnis von JavaScript nicht. Dementsprechend rächt es sich, Aufgaben gar nicht zu durchdenken, sondern alle Hoffnungen in ein Framework zu setzen.
Aktuelle JavaScript-Bücher erklären die Benutzung von Frameworks erst am Ende und führen vorher höchstens kleine Helferfunktionen ein (z.B. DOMhelp.js aus dem Buch Beginning JavaScript von Christian Heilmann). Das tun sie mit Recht – den tatsächlichen Entwicklungen entspricht aber eher das Gegenteil: Die Leute werden durch die Frameworks zu JavaScript gebracht, nicht umgekehrt. Deren Popularität liegt gerade darin, dass sie JavaScript zum convenience food, zum Fertiggericht machen. Diesem Umstand wurde bei der Vermittlung von JavaScript m.E. bisher noch nicht Rechnung getragen.
Viele meiner Anmerkungen klingen so, als würde ich mich gegen die jüngsten Umbrüche im JavaScript-Geschäft aussprechen. Dem ist nicht so. Durch die Verwerfungen liegt aber viel Arbeit vor uns, vor allem im Hinblick auf das Dokumentieren, Vermitteln und Lehren von JavaScript.
Einerseits sehe ich es nicht als die Aufgabe von SELFHTML an, Menschen die sinnvolle und korrekte Verwendung bestimmter Frameworks nahezulegen, die ihrerseits das Rad auf unterschiedliche Weise neu erfinden. Diese Aufgabe sollte deren Dokumentation erfüllen, schafft es aber nur selten. Andererseits gehört es zum notwendigen JavaScript-Grundwissen, Bibliotheken und Frameworks im Allgemeinen selbstbestimmt einsetzen (und bestenfalls selbst entwickeln) zu können und dabei jederzeit zu wissen, was man tut. Dem machen wiederum die gegenwärtig populären Monsterbibliotheken einen Strich durch die Rechnung.
Letztlich muss ein JavaScript-Tutorial, dass sich nicht gleich der völligen Abstraktion hingibt, auf die Unzulänglichkeiten der bestehenden APIs hinweisen, wiederkehrende Muster aufzeigen und Ansätze erklären, wie umständliche Wege durch Abstraktion vereinfacht werden können. Dafür erscheinen mir die besagten Minimal-Bibliotheken DOMHelp, DOMAssistant, forEach und ähnliche Ansätze gut geeignet zum Einstieg. Davon zu unterscheiden sind abgeschlossene Frameworks, die quasi eigene Meta-Sprachen einführen und sich vor der schrittweisen Vermittlung bisher sperren.
hallo Matthias,
gut geschrieben, wie alle deine Artikel. Allerdings: in welche Diskussion möchtest du damit hinein? Es wirkt eher wie ein kleines Selbstgespräch, das Appetit macht, nachzuschauen, was du nun für ein JavaScript-Tutorial schreiben wirst.
Grüße aus Berlin
Ich schließe mich Christoph an und gehe noch weiter: Es wirkt wie ein kleiner Monolog, der am Ende auf die eigene, sich durch all die angesprochenen Attribute abhebende JavasScript-Bibliothek, verweist - nur die vermisst man dann ;-)
Grüße, Sven
Hallo Molily,
die gleiche Diskussion betrifft aber nicht nur JavaScript, sondern eigentlich alle namhaften Script- und Programmiersprachen. Denn je bekannter, desto mehr vielgenutzte Frameworks, Libraries usw. gibt es dafür. Was ist denn noch Perl ohne CPAN? Oder PHP ohne PEAR? Aus Sicht der technischen Dokumentation entsteht da in der Tat ein großes Dilemma. Verzichtet man auf die Vermittlung der Basics und stürzt sich gleich auf irgendwelche Frameworks, lernen die Leser nicht die eigentliche Sprache, sondern nur, wie sie ein Framework bedienen. Verzichtet man auf die Vermittlung der Frameworks, lernen die Leser vielleicht, flüssig in Hashvariablen, for-Schleifen und try-catch-Statements zu denken, aber sie werden dazu neigen, alles zu Fuß und immer wieder neu erfinden zu wollen. Die gängige Praxis unter Buchautoren, die du ja auch beschreibst, erst mal die Basics zu vermitteln und am Ende noch etwas Framework-Programmierung dranzuhängen, ist angesichts dessen eigentlich verständlich. Aber wie du ebenfalls treffend bemerkst, kommen heute viele Anwender nicht mehr über die Basics zu den Frameworks, sondern eher umgekehrt: sie lernen irgendwie, ein bestimmtes Framework zu bedienen, stoßen auf Probleme, und werden erst dadurch auf Details der zugrunde liegenden Programmier-/Scriptsprache aufmerksam.
Ein Buch muss einen bestimmten Weg gehen. Hypertext muss das nicht. Hypertext kann alles parallel bieten: Einführung in die Basics der Sprache, Einführung in alle Frameworks, nackte Referenzen, und darüber gespannt diverse Guides und Verzeichnisse, durch die intelligente Verbindungen zwischen all den Einzelinhalten entstehen. Das Problem ist nur: wer soll all das schreiben? *g*
viele Grüße
Stefan Münz
Christoph,
ich verstehe deinen Kommentar nicht; ich denke, die Fragestellung des Artikels ist klar und bisher gab es m.W. dazu noch keine Diskussion, in die ich »rein« könnte.
Sven,
Da hast du unaufmerksam gelesen, ich habe es noch einmal verdeutlicht: Die genannten Namen sind bestehende Bibliotheken der Marke »Bau dir deine eigene kleine Bibliothek«, die auch im Artikel angesprochen und verlinkt werden. Zusammengefasst:
$(...)
-Stil zusammenstellt.Toller Artikel Mathias. Wer wirklich sinnvoll mit Erweiterungen und Frameworks umgehen will, muss die Grundlagen der Sprache beherrschen. Das gilt auch für JavaScript. Denn es ist bekannt, dass Ajax und mittlerweile etablierte Techniken auf JavaScript basieren. jQuery hat zB eine mäßige Syntax, Funktionsnamen beschreiben zB oft nicht, was die Funktion tut: ZB El.click(func) bindet einen Event-Listener, El.click dagegen triggert diesen manuell. Eher unschön.
Das ist für Anfänger gut und schön, aber wer die Sprache voll ausreizen will, muss die Grundlagen kennen - das was in SelfHTML steht.
Ich empfehle Prototype, hier wird man nicht von der Verantwortung entbunden, JavaScript zu lernrn ;)
Hallo molily,
wie so oft, hast Du doch bereits die meisten Antworten bei der gewohnt vielschichtigen Durchdringung eines komplexen Problems selbst an Tageslicht gewuchtet. Es kann natürlich auch sein, daß ich Deinen Grabungsansatz mißinterpretiere.
umfangreiches (re)zitieren:
... Diese neue Situation beschäftigt mich bei der Arbeit an einer kleinen
Einführung in JavaScript, da sie Fragen aufwirft wie »Soll man noch JavaScript
lernen oder gleich jQuery?« und »Wie hängt der Einsatz von Frameworks mit dem
Lernen von JavaScript zusammen?«
Zwischen Entwicklern von Bibliotheken-Plugins sowie Fertigscripten und den
JavaScript-Theoretikern scheint eine Kluft zu verlaufen. Diese drückt sich darin
aus, dass deren Standardwerke oftmals nicht rezipiert wurden ...
... Durch die Verwerfungen liegt aber viel Arbeit vor uns, vor allem im Hinblick
auf das Dokumentieren, Vermitteln und Lehren von JavaScript.
... Andererseits gehört es zum notwendigen JavaScript-Grundwissen, Bibliotheken
und Frameworks selbstbestimmt einsetzen (und bestenfalls selbst entwickeln) zu können
und jederzeit zu wissen, was man dabei tut.
... Den Prozess vom Spaghetticode zum Framework – von der Erfindung von
Helferfunktionen wie getElementsByClassName bis hin zu $("beliebige CSS- oder
XPath-Selektoren").chainability() – lief über viele Jahre. Diese Entwicklung
nachzuvollziehen wäre zum Verständnis aktueller Ansätze nötig, ist den meisten
aber nicht ohne weiteres möglich, da sie nie selbst Helferfunktionen entwickelt
haben, die den vorherigen Programmierstil grundlegend über den Haufen warfen.
... den Faden mit dem zuletzt zitierten Block aufnehmend ...
Von einem neuen Standardwerk zu den Grundlagen von JavaScript erwarte ich geradezu den historischen Rückblick (Vom DHTML zum DOM-Scritpting), da diese Entwicklung ein direktes Ergebnis der gewachsenen und wachsenden Fähigkeiten des BOM/DOM und des Erkenntnisgewinns beim Ausreizen dieser Features ist.
Gerade eine Einführung in die Grundlagen von JavaScript bietet die ideale Plattform, um anhand nur weniger Beispielscripten (Klassiker: clientseitige Formularvalidierung) stetig deren technisches Niveau zu heben. Aus Gründen der Schreib- und Denkfaulheit kapseln diese Beispiele dann einmal als wiederverwertbar erkannte funktionale Lösungen (z.b. [String].trim oder [Array].contains) als Methoden. Und abstrakte Konzepte wie das Iterieren von Listen können dann auch recht schnell die immer wiederkehrenden "(for ...; ...length; ++i)"-Schleifen ablösen, wobei die Implementationen eines jeden Iterators bzw. Accessors ebenfalls eigenständig erarbeitet wurde. Dieser Schritt könnte auch zum Ende hin geschehen, wenn man sich über komfortablere DOM-query-Methoden gedanken macht.
Da sich bis zum letztgenannten Punkt eine direkt auf der API des JavaScript-Sprachkerns
aufsetzende auf atomarer Ebene wunderbar modulare Bibliothek entwickelt hat, manövriert
man sich spätestens mit der sich schwieriger gestaltenden Kapselung zur DOM-Manipulation
in eine Zwickmühle. DOM-Objekte lassen sich nunmal nicht in jedem Browser prototypisch
erweitern.
Sperrt man jetzt die Gesamtheit aller entwickelten Module in einen eigenen
Namespace oder nur den DOM-Teil? Wie groß ist die Gefahr, daß die Bibliothek durch den
eigenen Namespace zum Monolithen wird? - der umfangreiche Einsatz komplexer DOM-Wrapper,
um [Node]s bzw. [NodeList]s abzubilden, erhöht jedenfalls diese Gefahr. Setzt man lieber
komplett auf generische Lösungen wie z.b. "Node.doOrGetSomething(elm, [,arg [, ...]])"?
Wie begegnet man all diesen Herausvorderungen konzeptionell?
Ein neues Standardwerk zu den Grundlagen von JavaScript müsste dieses Problem ebenfalls umfassend beleuchten.
@Stafan
» Das Problem ist nur: wer soll all das schreiben? *g*
Wenn sich ein Verlag zu einem zwei- ...eher dreibändigem Werk "JavaScript/DOM Scripting" - "JavaScript 2" mit dem Autorenteam Mathias Schäfer / Peter Seliger hinreißen lassen würde, wäre ich ernsthaft dabei, solange ich meine Familie ernähren könnte.
so long - peterS. - pseliger@gmx.net
Ad Stefan:
Ich bin ja kein Programmierer und kenne auch nicht viele Sprachen en detail, habe aber das Gefühl, dass JavaScript eine Sonderrolle im Hinblick auf Bibliotheken und Frameworks einnimmt. Beziehungsweise Frameworks in JavaScript erfüllen grundlegendere Aufgaben, deren Abstraktionsleistung ist eine andere.
Die meisten Web-Programmiersprachen bringen die wichtigsten Funktionen schon mit und es gibt einen relativ festen Rahmen. Dieser entwickelt sich weiter, aber relativ zentralisiert. Außerdem gibts nur einen relevanten Interpreter oder sie gleichen sich ziemlich. Zudem gibt eine festgelegte Struktur für interne Modularisierung und externe Erweiterbarkeit, sprich PEAR und Co. Man kann problemlos abgeleitete Klassen schreiben und so weiter, sodass man das Rad nicht neu erfinden muss.
In JavaScript ist das Angebot dürftig, da gibts erstmal verschiedene APIs verschiedener Herkunft, den Flickenteppich habe ich schon beschrieben. Eine Weiterentwicklung findet nicht statt oder halt dezentral bei den Browserherstellern (selbst wenn die die Standards nicht selbst entwickeln - sie implementieren sie letztlich unabhängig voneinander). Ein vordefiniertes System für Erweiterungen gibts nicht, stattdessen dominiert Wildwuchs. Selbst der Sprachkern ist unterschiedlich implementiert und es gibt proprietäre Erweiterungen. Die Erweiterung von Klassen (Prototypen) funktioniert nicht browserübergreifend. So muss ich letztlich unterschiedliche Scripte für die unterschiedlichen Interpreter und deren Features schreiben.
In der krassen Weise findet man eine solche zersplitterte und zerfaserte Situation m.W. nur bei JavaScript. Das räumt JavaScript-Frameworks einen besonderen Stellenwert und eine besondere Brisanz ein, weil es im Gegensatz zu anderen Sprachen für Standardaufgaben kein verlässliches Fundament gibt (man denke an so Basics wie Event-Handling!).
Was natürlich möglich ist, ist der Rückzug auf (bestehende und kommende) Standards und die Angleichung aller Browser auf dieses Niveau durch eine JavaScript-Bibliothek, die Implementierungslücken ergänzt. Den Ansatz verfolgt Dean Edwards mit base2.dom. Das Level, was damit hergestellt wird, würde ich mit dem anderer Programmiersprachen ohne Benutzung eines Frameworks vergleichen. Erst auf einer solchen Basis könnten sich Frameworks ausdifferenzieren, die sich auf verschiedene Programmierparadigmen ausrichten.
jQuery z.B. macht letzteres auch, gerade das unterscheidet solche Bibliotheken von bloßen »DHTML-Bibliotheken«, die es schon immer gab. Insofern werden Frameworks als solche in JavaScript erst gerade entdeckt. Trotzdem haben sie einen großen Fokus darauf, die Browserdifferenzen einzuebnen und den Umgang mit dem DOM zu vereinfachen. Das ist m.E. ein Grund, warum Kauderwelsch-Code so verbreitet ist.
Meine These ist halt, dass die Notwendigkeit der Abstraktion … beim gegenwärtigen, lückenhaften und unausgereiften ECMAScript und DOM quasi genetisch veranlagt
ist. Das würde ich bei anderen Sprachen nicht behaupten, weil sie von Haus aus eine stabilere Umgebung zur Verfügung stellen.
Die Entwicklung und Implementierung von Standards im Bereich JavaScript/DOM sehe ich in den Kinderschuhen, sodass ich die jetzigen Frameworks als eine Art Krisen- oder Übergangsphänomen werte. So gesehen lösen sie zum großen Teil Probleme an einer Stelle, die eigentlich nicht durch ein Framework, sondern die API bzw. Sprache gelöst werden sollten, wie es bei anderen Sprachen auch getan wird. Wenn in allen Browsern entsprechende Techniken nativ implementiert wären, wäre die Situation womöglich eine ganz andere. Dahin geht auch der Trend (HTML 5, neue DOM-Standards, ECMAScript Edition 4, Mozillas JavaScript-Extensions...), aber ziemlich langsam.