Der kleine Hot-Reload-Generator für statische Sites aus der Shell. Setzt Bash 4.4+ voraus.
ACHTUNG: Hier seid ihr Yaks!
Die Aufgabe von shite
besteht darin, mir bei der Erstellung meiner Website zu helfen: https://evalapply.org Daher wird der Umfang, der (falsche) Funktionsumfang und die Politur von shite
immer auf Produktionsniveau sein, wobei die Produktion „funktioniert auf meiner(n) Maschine(n)“ ist )" :)
Inhaltsverzeichnis
Nun ja, shite
zielt darauf ab, Websites zu erstellen.
Es handelt sich um ein kleines Veröffentlichungssystem, das aus Pipeline-Workflows besteht, die optional durch Streams von Dateiereignissen gesteuert werden (für die Hotreload-Bits).
Es wird einen Perl/PHP-Hacker aus dem letzten Jahrhundert nicht überraschen.
Es existiert, weil man alberne Melodien pfeift und Yaks rasiert.
Das ist im Grunde das, was es tut (siehe: die Funktion shite_templating_publish_sources
).
cat " ${watch_dir} /sources/ ${url_slug} " |
__shite_templating_compile_source_to_html ${file_type} |
__shite_templating_wrap_content_html ${content_type} |
__shite_templating_wrap_page_html |
${html_formatter_fn} |
tee " ${watch_dir} /public/ ${slug} .html "
# The complete "business logic" is 300-ish lines as of this comment,
# counted as all lines except comments and blank lines.
grep -E -v " s?#|^$ "
./bin/{events,metadata,templating,utils,hotreload}.sh |
wc -l
Bevor Sie sich zu sehr aufregen, möchte ich Sie warnen, dass es mir dank der MIT-Lizenz völlig egal ist, wenn dieser kleine Scheißmacher es nicht schafft, dass Ihr Scheiß funktioniert. Der Beitrag ist voller weiterer Warnungen.
Und zu guter Letzt beschließe ich hiermit, dass alle hierin enthaltenen Texte in Sean Connery Voish gelesen werden.
In meinen shite
Träumen wünsche ich mir...
Vor allem, um es (die „Geschäftslogik“) klein zu halten. Klein genug, um es in meinem Kopf zwischenzuspeichern, zu debuggen und umzugestalten.
Ohne Superuser-Erlaubnis zu installieren und zu verwenden.
Um Toolchains und Build-Abhängigkeiten vollständig zu vermeiden. Keine Edelsteine/npms/venvs/what-have-yous. Daher ist Bash die Sprache, weil Bash überall ist. Und Standardpakete wie pandoc
oder tidy
, wenn man bestimmte erweiterte Funktionen benötigt.
Abhängigkeitsfreie Vorlagen mit einfachem HTML in guten alten Heredocs.
Einfaches Metadatensystem, Content-Namespace, statische Asset-Organisation usw.
Webserver optional (oder jede Art von Serverprozess). Unser Ziel sind schließlich statische Websites, die mit file://
-Navigation problemlos funktionieren.
Es aus kleinen, zusammensetzbaren, rein funktionalen Unix-Tool-ähnlichen Teilen zu konstruieren, weil ich solche Dinge sehr mag.
Um mir einen nahtlosen REPL-ähnlichen Workflow zum Bearbeiten, Speichern, Erstellen und Vorschauen zu ermöglichen.
Nach einer langen Pause habe ich aus Versehen wieder mit dem Bloggen begonnen. Bevor ich Worte in die Cloud bringen konnte, habe ich mich mit „modernen“ Static Site Generators beschäftigt. Weil WordPress so aus dem letzten Jahrhundert stammt (so sagte ich es mir zumindest). Dann ärgerte mich die Magie der SSG Jamstack-Maßnahmen zur Erstellung von Vorlagen usw. Jetzt bin ich auf dem dunklen Weg, dies zu schaffen. Es wird darüber gebloggt unter: shite: static sites from shell: Teil 1/2
Ich verwende Shite hauptsächlich im „Hotreload“-Modus, hauptsächlich um Beiträge zu schreiben (im Organisationsmodus) und in der Live-Vorschau anzuzeigen (in Firefox). Weniger hauptsächlich zur Hot-Preview von Änderungen an Stilen und/oder Seitenvorlagen. Zumindest hauptsächlich, nachdem ich endlos an einem Beitrag gearbeitet habe, verwende ich ihn im Modus „Nicht Hotreload“, um eine vollständige Neuerstellung der Website durchzuführen.
Scheiß-Demo-Beispiele unten.
Im Grunde bedeutet das, dass, wenn ich eine Datei unter sources
erstelle, aktualisiere oder lösche, diese automatisch in HTML übersetzt, lokal public
veröffentlicht werden und im Webbrowser, in dem meine Website geöffnet ist, eine entsprechende Seitennavigation oder Neuladeaktion auslösen muss.
Rufen Sie das „Haupt“-Skript in einer sauberen neuen Terminalsitzung oder einem tmux-Bereich auf.
./shite.sh
Es öffnet hilfreicherweise die Indexdatei in Firefox, gemäß den Standardeinstellungen, die ich im Array shite_global_data
in ./shite.sh
festgelegt habe.
Öffnen Sie in Ihrem Emacs oder Vim eine Inhaltsdatei unter sources
. Bearbeiten, speichern und beobachten Sie, wie der Inhalt im Browser angezeigt wird. (Ja, die Angabe von Emacs/Vim ist albern, weil ich heiße Aktionen basierend auf Inotify-Ereignissen auslöse. Anscheinend führen verschiedene Editoren Dateiaktualisierungen unterschiedlich durch. Ich verwende Emacs oder Vim, also achte ich auf die Ereignisse, die sie verursachen, damit es auf meinem Computer funktioniert. : )).
Häufig merkt sich der Browser die Scrollposition, was praktisch ist. Manchmal ist das Hotreload scheiße. Also drücke ich einfach die Leertaste und speichere die Inhaltsdatei, um Hotreload erneut auszulösen.
Gehen Sie zu einem statischen Asset, z. B. einem CSS-Stylesheet. Ändern Sie etwas, beispielsweise den Wert der Hintergrundfarbe. Speichern Sie und beobachten Sie den Farbwechsel im Browser.
Optimieren Sie einige Vorlagenfragmente in templates.sh
– sagen wir, Blog-Beitragsvorlage. Wechseln Sie dann zu einer Inhaltsdatei für einen Blogbeitrag und ändern Sie sie, um die Seitenerstellung mit der geänderten Vorlage auszulösen (drücken Sie beispielsweise die Leertaste und speichern Sie sie).
Das ist ein Hack. Die Root-Seite index.org unter „Quellen“ ist etwas Besonderes. Wenn ich es ändere, bedeutet das, dass ich Beitragslisten für die Indexseite und für Tags neu erstellen möchte und auch zugehörige Metadateien wie RSS-Feed, Sitemap, robots.txt usw. neu erstellen möchte.
Rufen Sie shite.sh
in einer sauberen neuen Terminalsitzung mit „no“ und optional mit der base_url
der Bereitstellungsumgebung auf:
Erstellen Sie die gesamte Website für die „lokale“ file:///-Navigation neu. Wirklich „serverlos“ :)
./shite.sh " no "
Erstellen Sie die vollständige Website für die Veröffentlichung unter meiner Domain neu.
./shite.sh " no " " https://evalapply.org "
Diese Flags verändern das Verhalten des Systems.
SHITE_BUILD
auf „hot“ setzen, wird das Ereignissystem im „Monitor“-Modus ausgeführt, was wiederum das Hotreload-Verhalten steuert. Wenn Sie es auf „Nein“ setzen, wird das Hotreload des Browsers unterdrückt.SHITE_DEBUG_TEMPLATES
auf „debug“ setzen, werden zunächst Vorlagen als Quelle ermittelt, bevor Vorlageninhalte veröffentlicht werden. shite
ist im Inneren ziemlich Unixy. Zumindest würde ich das gerne glauben.
Code ist Bash im funktionalen Programmierstil. Alles ist eine Funktion. Die meisten Funktionen sind reine Funktionen – kleine Unix-Tools für sich. Die meiste Logik ist Pipeline-orientiert. Das funktioniert überraschend gut, denn Shell ist kein schlechter Ort für FP.
Ich wollte beim Schreiben mit shite
auch ein interaktives Live-REPL-ähnliches Erlebnis haben, weil ich gerne in Live-/interaktiven Laufzeitumgebungen wie Clojure und Emacs arbeite.
shite
ist also zu einem vollständig reaktiven, ereignisgesteuerten System geworden, das Hot-Builds und beim Speichern neu laden kann.
Es gibt drei Hauptverzeichnis-Namespaces:
sources
, die den „Quell“-Inhalt enthalten, wie zum Beispiel im Orgmode verfasste Blogbeiträge, sowie CSS, Javascript und andere statische Assets.public
Ziel für die kompilierten/gebauten Artefaktebin
für den beschissenen Baucode Das URL-Benennungsschema folgt der Unterverzeichnisstruktur unter sources
und wird unverändert unter der pubilic
Verzeichnisstruktur repliziert. Da es sich um ein Standard-URL-Namespace-Schema handelt, gilt es auch direkt für veröffentlichte Inhalte. Etwa so:
file:///absolute/path/to/shite/posts/slug/index.html
http://localhost:8080/posts/slug/index.html
https://your-domain-name.com/posts/slug/index.html
Alle „öffentlichen“ Funktionen haben den Namensraum shite_the_func_name
. Alle „privaten“ Funktionen haben den Namensraum __shite_the_func_name
.
Es gibt Funktionen für:
In einer sauberen neuen Terminalsitzung:
source ./bin/utils_dev.sh
shitTABTAB
oder __shiTABTAB
in der Befehlszeile für automatische Vervollständigungen.type -a func_name
ein, um die Definition der Funktion zu drucken und ihre API zu lesen.shite_global_data
und shite_page_data
nach Bedarf fest. Es gibt Vorlagen für Seitenfragmente (wie Kopfzeile, Fußzeile, Navigation) und für vollständige Seitendefinitionen (wie die Standardseitenvorlage). Diese sind als einfaches HTML geschrieben, das in Heredocs verpackt ist. ./bin/templates.sh
stellt diese bereit.
Vorlagen werden mit variablen Daten aus verschiedenen Quellen gefüllt:
shite_global_data
enthält seitenweite Metadaten und shite_page_data
enthält seitenspezifische Metadaten. Ein externer Prozess muss diese Arrays vor der Verarbeitung einer Seite vorab festlegen.Eine vollständige Seite kann beispielsweise wie folgt aufgebaut sein:
cat ./sample/hello.md |
pandoc -f markdown -t html |
cat << EOF
<!DOCTYPE html>
<html>
<head>
$( shite_template_common_meta )
$( shite_template_common_links )
${shite_page_data[canonical_url]}
</head>
<body ${shite_page_data[page_id]} >
$( shite_template_common_header )
<main>
$( cat - )
</main>
$( shite_template_common_footer )
</body>
</html>
EOF
Das Metadatensystem von shite
ist als Schlüssel-Wert-Paare definiert. Schlüssel benennen die Metadatenelemente und werden mit jedem Wert dieses Typs verknüpft. Beispiele unten.
Wie bereits erwähnt, werden Laufzeitmetadaten in der Umgebung durch die assoziativen Arrays shite_global_data
und shite_page_data
übertragen. Diese können durch direkte Konstruktion gefüllt oder aus externen Quellen aktualisiert werden.
Jede Seite kann ihre eigenen Metadaten im „Titelthema“ oben auf der Seite angeben. Dazu werden zusätzlich Seitenmetadaten verwendet, die aus anderen Quellen stammen.
shite
erwartet von uns, dass wir Titeltexte mit einer Syntax schreiben, die mit dem jeweiligen Inhaltstyp kompatibel ist, wie folgt.
Verwenden Sie Kommentarzeilen # SHITE_META
um die Metadaten im Organisationsstil abzugrenzen, die shite
auch als seitenspezifische Metadaten analysieren soll.
# SHITE_META
#+title: This is a Title
#+slug: this/is/a/slug
#+date: Friday 26 August 2022 03:38:01 PM IST
#+tags: foo bar baz quxx
# SHITE_META
#+more_org_metadata: but not processed as shite metadata
#+still_more_org_metadata: and still not processed as shite metadata
* this is a top level heading
this is some orgmode content
#+TOC: headlines 1 local
** this is a sub heading
- this is a point
- this is another point
- a third point
Schreiben Sie den YAML-Titeltext im Jekyll-Stil, eingerahmt zwischen ---
Trennzeichen.
---
TITLE : This is a Title
slug : this/is/a/slug
DATE : Friday 26 August 2022 03:38:01 PM IST
TAGS : foo BAR baz QUXX
---
# this is a heading
this is some markdown content
## this is a subheading
- this is a point
- this is another point
- a third point
Wir können einfach Standard- <meta>
-Tags verwenden, die dieser Konvention entsprechen: <meta name="KEY" content="value">
.
< meta name =" TITLE " content =" This is a Title " >
< meta name =" slug " content =" this/is/a/slug " >
< meta name =" DATE " content =" Friday 26 August 2022 03:38:01 PM IST " >
< meta name =" TAGS " content =" foo BAR baz QUXX " >
< h1 > This is a heading </ h1 >
< p > This is some text </ p >
< h2 > This is a subheading </ h2 >
< p >
< ul >
< li > This is a point </ li >
< li > This is another point. </ li >
< li > This is a third point. </ li >
</ ul >
</ p >
Hier sind Yaks!
Da ich völlig verwöhnt bin von insta-erfreulichen interaktiven Live-Workflows im Clojure-/Lisp-/Spreadsheet-Stil, möchte ich auch Hot-Reload und Hot-Navigation beim Shite-Making.
Aber es scheint keinen eigenständigen Live-Webentwicklungsserver/-tool zu geben, der nicht auch möchte, dass ich die Hälfte der bekannten Internet-Abhängigkeiten herunterlade. Wie ich bereits sagte, etwas, was ich absolut nicht tun möchte.
DuckSearch hat den Emacs-Ungeduld-Modus bereitgestellt, der ziemlich heiß ist, aber ich möchte dies nicht fest mit meinen Emacs verdrahten. Glücklicherweise lieferte es auch diesen aufregenden Geistesblitz mit „inotify-tools“ und „xdotool“: github.com/traviscross/inotify-refresh
Heißes Exemplar!
Denn was könnte heißer sein, als wenn mein Computer für mich die F5-Taste drückt? Als ob es tief in meinem Herzen wüsste , was ich wirklich wollte.
Das Ereignissubsystem ist orthogonal zu allem anderen und bildet eine Einheit mit dem Rest des Systems.
Das Design entspricht einer Standard-Streaming-Architektur, nämlich. Achten Sie auf Dateisystemereignisse, filtern, deduplizieren, analysieren und leiten Sie sie an verschiedene Ereignisprozessoren weiter. Derzeit gibt es nur zwei solcher Prozessoren; eine zum Kompilieren und Veröffentlichen der mit dem Ereignis verknüpften Seite oder des Assets, eine andere zum Hot-Neuladen des Browsers (oder zum Hot-Navigieren) je nach demselben Ereignis.
Im Prinzip das hier:
# detect file events
__shite_detect_changes ${watch_dir} ' create,modify,close_write,moved_to,delete ' |
__shite_events_gen_csv ${watch_dir} |
# hot-compile-and-publish content, HTML, static, etc.
tee >( shite_templating_publish_sources > /dev/null ) |
# browser hot-reload
tee >( __shite_hot_cmd_public_events ${window_id} ${base_url} |
__shite_hot_cmd_exec )
Ereignisse sind einfach ein Stream von CSV-Datensätzen, der wie folgt strukturiert ist:
unix_epoch_seconds,event_type,base_dir,sub_dir,url_slug,file_type,content_type `
Wir verwenden verschiedene Teile des Ereignisdatensatzes, um unterschiedliche Arten von Aktionen auszulösen.
Das oben verlinkte inotify-refresh-Skript versucht, eine Reihe von Browserfenstern regelmäßig zu aktualisieren. Wir wollen jedoch sehr gespannt sein. Jede Bearbeitungsaktion an unseren Inhaltsdateien und/oder statischen Assets muss sofort Hot-Reload-/Navigationsaktionen im Browser-Tab auslösen, auf dem unser Inhalt angezeigt wird.
Wir möchten unterschiedliche Neuladeszenarien definieren: Sich gegenseitig ausschließende, kollektiv umfassende Buckets, denen wir Dateiereignisse zuordnen können, die wir überwachen möchten.
Wenn wir dies tun, können wir Aktualisierungen als eine Art Vorausschreibprotokoll modellieren, indem wir Ereignisse durch eine Analysepipeline leiten, sie mit dem Szenario mit exakter Übereinstimmung verknüpfen und dann schließlich die Aktion auslösen. Zum Beispiel:
Aktuelle Registerkarte aktualisieren, wenn
Geh wann nach Hause
Navigieren Sie zum Inhalt, wenn
Da wir den Computer dazu bringen, unsere eigenen Tastaturaktionen zu emulieren, kann er unsere persönlichen Aktionen beeinträchtigen. Wenn wir uns darauf beschränken, unsere Scheiße in unserem Texteditor zu schreiben und den Computer das Hotreloading erledigen lassen, sollten wir uns nicht darüber ärgern.
Es gibt viele Yaks auf der Welt.
Für ein wirklich umfassendes Multi-Site-Publishing-Mojo:
shite
sollte auf meinem PATH verfügbar seinDas ist ein kleines Yak. Ich werde es wahrscheinlich bald rasieren.
Offensichtlich kann man die CI-Jobs beliebter Git-Hosts verwenden, um shite
Builds auszulösen. Aber warum sollte man klobige Technologie des aktuellen Jahrhunderts verwenden, wenn wir bereits den Stand der Technik des späten 20. Jahrhunderts erreicht haben ... vollständig streamend und vollständig reaktiv?
Abgesehen von Sarcasam verstehe ich nicht, warum dasselbe Ereignissystem nicht verwendet werden kann, um Hot-Deploy-Unterstützung auf einem von mir ausgeführten Remote-Computer hinzuzufügen.
Auf der Remote-Box:
sources
ist verankertsources
live (abzüglich der Browserüberwachung).Auf meiner lokalen Box:
https://mydomain.com/posts/hello/index.html
Führen Sie über SSH etwas aus, um die Browseraktualisierung wieder auf die lokale Box zu bringen, im Falle von Hot-Deployments auf dem Remote-Server.
Vielleicht ein Setup-/Abbau-Szenario für „Entwickeln/Entwerfen“? Vielleicht eine „dev_server“-Funktion, die wir verwenden, um eine neue Sitzung zum Schreiben von Mist anzustoßen?
Wenn Sie bis hierher gekommen sind und trotzdem einen Beitrag leisten möchten ...
Warum?
Warum im Namen von allem, was heilig und gut ist, solltest du das wollen? Ist es nicht völlig offensichtlich, dass dies das Werk eines Trottels ist? Haben Sie noch nicht gehört, dass Bash nicht einmal eine echte Programmiersprache ist? Und ist es nicht offensichtlich, dass Ihre PRs für immer dahinsiechen und Ihre Kommentare im namenlosen Nichts versinken werden?
Ja, Patches zu verschicken ist eine schreckliche Idee.
Aber bitte mailen Sie mir Ihre Hoffnungen und Träume bezüglich Ihres Scheißmachers! Ich habe E-Mails mit meinem Vornamen, Punkt Nachnamen bei Google Mail gelesen.
Gemeinsam können wir alberne Melodien pfeifen und unsere jeweiligen Yaks auf unsere ganz eigene Art gemeinsam rasieren.
Möge die Quelle mit uns sein.
Dieses Werk ist unter der MIT-Lizenz und der CC By-SA 4.0-Lizenz doppelt lizenziert.
SPDX-Lizenz-Identifier: mit OR cc-by-sa-4.0