Alpine.js: Das JavaScript-Framework, das wie jQuery verwendet wird, wie Vue geschrieben ist und von TailwindCSS inspiriert ist

Avatar of Hugo Di Francesco
Hugo Di Francesco am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Wir haben große JavaScript-Frameworks, die bereits von vielen Leuten genutzt und gemocht werden, darunter React, Vue, Angular und Svelte. Brauchen wir eine weitere JavaScript-Bibliothek? Werfen wir einen Blick auf Alpine.js und Sie können selbst entscheiden. Alpine.js richtet sich an Entwickler, die *keine* Single-Page-Anwendung (SPA) erstellen möchten. Es ist leichtgewichtig (~7kB gzipped) und dafür konzipiert, Markup-gesteuertes clientseitiges JavaScript zu schreiben.

Die Syntax ist von Vue und Angular-Direktiven entlehnt. Das bedeutet, sie wird Ihnen vertraut vorkommen, wenn Sie bereits damit gearbeitet haben. Aber, noch einmal, Alpine.js ist nicht dafür gedacht, SPAs zu erstellen, sondern vielmehr Ihre Vorlagen mit einem *kleinen* bisschen JavaScript zu erweitern.

Hier ist zum Beispiel eine Alpine.js-Demo einer interaktiven "Alert"-Komponente.

Die Alarmmeldung ist über x-model="msg" an das Eingabefeld gebunden (Two-way-Binding). Der "Level" der Alarmmeldung wird über eine reaktive level-Eigenschaft gesetzt. Der Alarm wird angezeigt, wenn sowohl msg als auch level einen Wert haben.

Es ist wie ein Ersatz für jQuery und JavaScript, aber mit deklarativer Darstellung

Alpine.js ist ein Ersatz im Vue-Template-Stil für jQuery und Vanilla JavaScript, kein *Konkurrent* von React/Vue/Svelte/WhateverFramework.

Da Alpine.js weniger als ein Jahr alt ist, kann es Annahmen über DOM-APIs machen, die jQuery nicht machen kann. Ziehen wir kurz einen Vergleich zwischen den beiden.

Abfragen vs. Binden

Der Großteil von jQuerys Größe und Funktionen besteht aus einer plattformübergreifenden Kompatibilitätsschicht über imperative DOM-APIs – dies wird üblicherweise als jQuery Core bezeichnet und bietet Funktionen zum Abfragen und Manipulieren des DOM.

Die Antwort von Alpine.js auf jQuery Core ist eine deklarative Methode, um Daten mit der x-bind Attribut-Bindungsdirektive an das DOM zu binden. Sie kann verwendet werden, um jedes Attribut an reaktive Daten auf der Alpine.js-Komponente zu binden. Alpine.js bietet, wie seine Zeitgenossen bei deklarativen View-Bibliotheken (React, Vue), x-ref als Fluchtmöglichkeit, um direkt auf DOM-Elemente aus dem JavaScript-Komponentencode zuzugreifen, wenn das Binden nicht ausreicht (z. B. bei der Integration einer Drittanbieterbibliothek, der ein DOM-Knoten übergeben werden muss).

Ereignisbehandlung

jQuery bietet auch eine Möglichkeit, Ereignisse zu behandeln, zu erstellen und auszulösen. Alpine.js stellt die x-on Direktive und den magischen Wert $event zur Verfügung, der es JavaScript-Funktionen ermöglicht, Ereignisse zu behandeln. Zum Auslösen von (benutzerdefinierten) Ereignissen bietet Alpine.js die magische Eigenschaft $dispatch, die ein dünner Wrapper über die Event- und Dispatch-Event-APIs des Browsers ist.

Effekte

Eine der Hauptfunktionen von jQuery sind seine Effekte, oder besser gesagt, seine Fähigkeit, einfache Animationen zu schreiben. Wo wir in jQuery slideUp, slideDown, fadeIn, fadeOut Eigenschaften verwenden könnten, um Effekte zu erzeugen, bietet Alpine.js eine Reihe von x-transition Direktiven, die Klassen während des Übergangs des Elements hinzufügen und entfernen. Das ist stark vom Vue Transition API inspiriert.

Auch das Ajax-Client von jQuery hat in Alpine.js keine präskriptive Lösung, dank der Fetch API oder der Nutzung einer Drittanbieter-HTTP-Bibliothek (z. B. axios, ky, superagent).

Plugins

Auch jQuery-Plugins sind erwähnenswert. Dem steht (noch) nichts im Alpine.js-Ökosystem gegenüber. Das Teilen von Alpine.js-Komponenten ist relativ einfach und erfordert in der Regel eine einfache Kopie und Einfügung. Der JavaScript-Code in Alpine.js-Komponenten sind "nur Funktionen" und greifen tendenziell nicht auf Alpine.js selbst zu, was sie relativ einfach teilbar macht, indem sie mit einem script-Tag auf verschiedenen Seiten eingebunden werden. Jegliche magischen Eigenschaften werden hinzugefügt, wenn Alpine initialisiert wird oder in Bindungen übergeben wird, wie z. B. $event in x-on-Bindungen.

Es gibt derzeit keine Beispiele für Alpine.js-Erweiterungen, obwohl es einige Issues und Pull Requests gibt, um "Core"-Ereignisse hinzuzufügen, die sich von anderen Bibliotheken in Alpine.js einklinken. Es finden auch Diskussionen über die Möglichkeit statt, benutzerdefinierte Direktiven hinzuzufügen. Die Haltung des Erstellers von Alpine.js, Caleb Porzio, scheint darin zu bestehen, API-Entscheidungen auf den Vue-APIs zu basieren, sodass ich erwarte, dass jeder zukünftige Erweiterungspunkt von dem inspiriert sein wird, was Vue.js bietet.

Größe

Alpine.js ist leichter als jQuery und kommt auf 21,9 KB minimiert — 7,1 KB gzippt — im Vergleich zu jQuery mit 87,6 KB minimiert — 30,4 KB minimiert und gzippt. Nur 23% der Größe!

Der Großteil davon ist wahrscheinlich auf die Art und Weise zurückzuführen, wie Alpine.js sich darauf konzentriert, eine deklarative API für das DOM bereitzustellen (z. B. Attributbindung, Ereignislistener und Übergänge).

Bundlephobia teilt die beiden auf

Zum Vergleich: Vue kommt auf 63,5 KB minimiert (22,8 KB gzippt). Wie kann Alpine.js leichter sein, obwohl seine API gleichwertig mit Vue ist? Alpine.js implementiert keinen Virtual DOM. Stattdessen mutiert es das DOM direkt und stellt dieselbe deklarative API wie Vue zur Verfügung.

Schauen wir uns ein Beispiel an

Alpine ist kompakt, weil der Anwendungscode deklarativer Natur ist und über Vorlagen deklariert wird. Hier ist zum Beispiel eine Pokémon-Suchseite, die Alpine.js verwendet

Dieses Beispiel zeigt, wie eine Komponente mit x-data und einer Funktion eingerichtet wird, die die anfänglichen Komponentendaten, Methoden und x-init zur Ausführung dieser Funktion beim Laden zurückgibt.

Bindungen und Ereignislistener in Alpine.js mit einer Syntax, die stark an Vue-Vorlagen erinnert.

  • Alpine: x-bind:attribute="express" und x-on:eventName="expression", Kurzformen sind :attribute="expression" und @eventName="expression".
  • Vue: v-bind:attribute="express" und v-on:eventName="expression", Kurzformen sind :attribute="expression" und @eventName="expression".

Das Rendern von Listen wird mit x-for auf einem template-Element erreicht und die bedingte Darstellung mit x-if auf einem template-Element.

Beachten Sie, dass Alpine.js keine vollständige Vorlagensprache bietet, daher gibt es keine Interpolationssyntax (z. B. {{ myValue }} in Vue.js, Handlebars und AngularJS). Stattdessen erfolgt die Bindung von dynamischen Inhalten mit den Direktiven x-text und x-html (die direkt den zugrundeliegenden Aufrufen von Node.innerText und Node.innerHTML entsprechen).

Ein gleichwertiges Beispiel mit jQuery ist eine Übung, die Sie gerne übernehmen können, aber der klassische Stil umfasst mehrere Schritte

  • Imperatives Binden an den Button-Klick mit $('button').click(/* callback */).
  • Innerhalb dieses "Click-Callbacks" den Eingabewert aus dem DOM abrufen und dann verwenden, um die API aufzurufen.
  • Nach Abschluss des Aufrufs wird das DOM mit neuen Knoten aktualisiert, die aus der API-Antwort generiert wurden.

Wenn Sie an einem Seitenvergleich desselben Codes in jQuery und Alpine.js interessiert sind, hat Alex Justesen einen Zeichenzähler in jQuery und in Alpine.js erstellt.

Wieder im Trend: HTML-zentrierte Werkzeuge

Alpine.js ist von TailwindCSS inspiriert. Die Einführung von Alpine.js im Repository lautet "Tailwind für JavaScript".

Warum ist das wichtig?

Eines der Verkaufsargumente von Tailwind ist, dass es "Low-Level-Utility-Klassen bietet, mit denen Sie vollständig benutzerdefinierte Designs erstellen können, ohne jemals Ihre HTML zu verlassen." Genau das macht Alpine. Es funktioniert innerhalb von HTML, sodass kein Bedarf besteht, innerhalb von JavaScript-Vorlagen zu arbeiten, wie es bei Vue oder React der Fall wäre. Viele der von der Community zitierten Alpine-Beispiele verwenden nicht einmal Skript-Tags!

Schauen wir uns ein weiteres Beispiel an, um den Unterschied deutlich zu machen. Hier ist ein barrierefreies Navigationsmenü in Alpine.js, das keinerlei Skript-Tags verwendet.

Dieses Beispiel nutzt aria-labelledby und aria-controls außerhalb von Alpine.js (mit id-Referenzen). Alpine.js stellt sicher, dass das "Toggle"-Element (ein Button) ein aria-expanded-Attribut hat, das auf true gesetzt ist, wenn die Navigation geöffnet ist, und auf false, wenn sie geschlossen ist. Diese aria-expanded-Bindung wird auch auf das Menü selbst angewendet, und wir zeigen/verbergen die Linkliste darin, indem wir an hidden binden.

Markup-zentriert zu sein bedeutet, dass Alpine.js und TailwindCSS-Beispiele einfach zu teilen sind. Alles, was Sie brauchen, ist ein Kopieren und Einfügen in HTML, das auch Alpine.js/TailwindCSS ausführt. Keine verrückten Verzeichnisse voller Vorlagen, die kompiliert und in HTML gerendert werden!

Da HTML ein grundlegender Baustein des Webs ist, ist Alpine.js ideal für die Erweiterung von serverseitig gerenderten (Laravel, Rails, Django) oder statischen Websites (Hugo, Hexo, Jekyll). Die Integration von Daten mit dieser Art von Werkzeug kann so einfach sein wie das Ausgeben von JSON in die x-data="{}"-Bindung. Die Möglichkeit, etwas JSON von Ihrem Backend/Ihrer statischen Website-Vorlage direkt in die Alpine.js-Komponente zu übergeben, vermeidet den Aufbau eines "weiteren API-Endpunkts", der einfach nur einen Datenschnipsel liefert, der von einem JavaScript-Widget benötigt wird.

Client-seitig ohne Build-Schritt

Alpine.js ist *dafür konzipiert*, als direkter Skript-Include von einem öffentlichen CDN verwendet zu werden. Die Entwicklererfahrung ist darauf abgestimmt. Deshalb ist es ein großartiger Vergleich und Ersatz für jQuery: Es wird einfach eingefügt und eliminiert einen Build-Schritt.

Obwohl es nicht traditionell so verwendet wird, kann die gebündelte Version von Vue direkt verlinkt werden. Sarah Drasner hat einen ausgezeichneten Artikel, der Beispiele dafür zeigt, wie jQuery durch Vue ersetzt wird. Wenn Sie Vue jedoch ohne Build-Schritt verwenden, verzichten Sie aktiv auf

  • die Vue CLI
  • Single-File-Komponenten
  • kleinere/optimiertere Bundles
  • eine strenge CSP (Content Security Policy), da Vue Inline-Vorlagen Ausdrücke clientseitig auswerten

Ja, obwohl Vue eine buildlose Implementierung bietet, hängt seine Entwicklererfahrung stark von der Vue CLI ab. Das Gleiche gilt für Create React App für React und die Angular CLI. Ein Build-loser Ansatz beraubt diese Frameworks ihrer besten Eigenschaften.

Da haben Sie es! Alpine.js ist eine moderne, CDN-first Bibliothek, die deklarative Darstellung für eine kleine Payload bietet – und das alles ohne den Build-Schritt und die Vorlagen, die andere Frameworks benötigen. Das Ergebnis ist ein HTML-zentrischer Ansatz, der nicht nur einem modernen jQuery ähnelt, sondern auch ein großartiger Ersatz dafür ist.

Wenn Sie nach einem jQuery-Ersatz suchen, der Sie nicht zu einer SPA-Architektur zwingt, dann probieren Sie Alpine.js aus! Interessiert? Mehr erfahren Sie auf Alpine.js Weekly, einer kostenlosen wöchentlichen Zusammenfassung von Alpine.js Nachrichten und Artikeln.