Ich liebe Vue.js von Evan You und ich mag statische Webseiten. Natürlich gibt es bereits Lösungen um diese beiden Neigungen miteinander zu verbinden wie VuePress oder Nuxt. Aber wäre ich ein Programmierer, wenn ich diesen einfachen Weg wählen würde?
Natürlich wollte ich ran an die bleeding edge und habe mich schnell begeistern lassen von Evans neuestem Coup vite. Es wirft den Ballast vom webpack über Bord und macht alles richtig. Zunächst versuchte ich damit und mit vitepress mein Glück, aber das war leider auch nicht ganz das wonach ich suchte.
Also ging ich noch mal einen Schritt zurück und schaute mir die Klassiker der statischen Website Generierung an: Gatsby, Hugo, Jekyll und 11ty. Auch diese machten eigentlich alles richtig, aber alles kam dort auch nicht von der Stange wie ich es gerne hätte. Besonders da ich mich SeaSite schon eine eigene Lösung gebaut hatte, mit der alle meine Websites generiert wurden.
Was will ich eigentlich?
Aber was war es also, was ich wollte? Ich habe folgende Punkte für mich herausgefunden:
- Geschwindigkeit: Ich möchte wie bei Vue.js Änderungen im Code vornehmen und unmittelbar im Browser das Ergebnis sehen.
- Flexibilität: Ich möchte jeden Aspekt selber beeinflussen und Programmieren können. Am liebsten in Javascript.
- Nachbearbeitung: Ich möchte Inhalte noch leicht anpassen können, nachdem sie bereits Berechnet wurden. Das war das Kernprinzip von SeaSite, wodurch ich im Nachgang Optimierungen an Bildern und Videos vornehmen konnte, aber auch Übersetzungen von Textpassagen für verschiedene Sprachversionen laufen lassen konnte.
Wie mache ich es?
Gut, bei Punkt 1 hatte ich bei vite schon esbuild entdeckt. Es ist so unglaublich schnell, dass ich es gar nicht glauben konnte. Das Ergebnis ist auch zuverlässig und genau so wie es sein soll. Esbuild war also gesetzt als Werkzeug, das ich einsetzen wollte.
Ich baute also zunächst ein kleines Node.js Skript, dass eine Javascript Datei transpilierte. Dazu baute ich eine kleine Library, um Routen zu registrieren. Die Generierung der Inhalte sollte dann on-demand erfolgen, wenn die Website durch einen einfachen Express.js Webserver angefragt würde. Um die statischen Seiten zu generieren würde ich einfach zu allen registrierten Routen die Inhalte generieren und abspeichern lassen. Das ging super und dauerte nur Millisekunden.
Schnell wollte ich nun auch den Komfort von vite haben, d.h. wenn Dateien sich ändern, lädt auch der Browser unmittelbar neu. Mit Chokidar konnte ich den Ordner mit den JS Dateien beobachten und per esbuild alles neu übersetzen lassen. Durch einen kleinen Trick, ließ sich der Import-Cache von Node.js umgehen und das neue JS einladen und ausführen. Mit socket.io war schnell ein Reload Mechanismus für den Browser zusammengebaut.
Jetzt soll alles schöner werden!
Ich hatte nun endgültig Feuer gefangen und es gab kein zurück mehr. Dann konnte es auch schöner werden :) Es gelang mir leider nicht auf Anhieb Vue.js einzubinden, allerdings zweifelte ich auch, ob das überhaupt sinnvoll sei. In SeaSite hatte ich bereits JSX und JSDOM eingesetzt. Für ein anderes Projekt hatte ich bereits eine DOM Abstraktion geschrieben, die sehr schlank ist. Diese baute ich nun so aus, dass damit per JSX einfach HTML und XML generiert worden konnte.
Somit war eine Manipulation der Inhalte durch einfache DOM Aktionen möglich. Wie viel schöner wäre es aber, wenn die entsprechenden Nodes per CSS-Selektoren gefunden werden könnten. Also baute ich auch das mit css-parse ein und es funktionierte wunderbar.
Auch ein Markdown-Parser war aus SeaSite schon vorhanden und wurde nur noch entsprechend ausgebaut, dass unter Beibehaltung der angenehmen Geschwindigkeit die Meta-Daten für die Registrierung von Routen zur Verfügung standen.
Open Source!
Nun war also alles an Bord was benötigt wurde und es wurde Zeit eine einfache einheitliche Struktur zu schaffen, um das Projekt veröffentlichen zu können. Ein erstes Ziel war die Routen durch einfache Datenstrukturen zu beschreiben, um maximale Flexibilität zu erhalten. Für gängige Formate wie HTML, XML, JSON, Text und Assets wurden bequeme Methoden erstellt.
Da nun schon ohnehin alles die Anmutung eines Webservers hatte, der eben auch statische Seiten ausspucken kann, lag es nahe das smarte Middleware Muster von Koa.js zu übernehmen. Auf diese Weise sind Templates und Plugins leicht zu realisieren. Eine Kopie der genannten Datenstruktur dient dann als Kontext und das Ergebnis wird im Property ctx.body
erwartet.
Hier ist es nun, das fertige Projekt. Ich würde mich sehr über Hilfe und Ideen freuen. Vielleicht ist es nicht das tollste Tool, um statische Websites zu erzeugen, aber eventuell die Basis für eine noch smartere Lösung die darauf aufbaut.
https://www.npmjs.com/package/hostic
Im Folgenden werde ich einige Themen weiter beleuchten wollen, die sich aus der Erstellung einer Website ergeben und wie diese mit Hostic gelöst werden können. Die Liste der aktuellen Ideen zu Themen:
- Aufbau einer einfachen statischen Website mit Hostic
- Aufbau eines Blogs mit Markdown
- Aufbau einer Mehrsprachigen Website und Lokalisierung
- Optimierungen für Suchmaschinen und Accessibility
- Hosting: Beaker Browser, sh…
Diese Webseiten wurden bereits von Hostic erstellt:
Veröffentlicht am 2. September 2020