Das Formatieren ist der Teil des Code-Workflows, den niemand bemerkt, bis er fehlt: Ein HTML-Block liest sich wie ein einziges langes Wort, und derselbe Block wird zu einem Baum, sobald die Einrückung stimmt. Ein Formatter ändert nicht, was Ihr Mark-up bedeutet, er ändert, was es kostet, ihn anzusehen, und genau da verschwimmt ein Großteil der Debugging-Zeit. Der HTML-Formatierer läuft vollständig in Ihrem Browser: Sie fügen das Mark-up ein, wählen einen Modus, und das Ergebnis erscheint im daneben liegenden Feld. Nichts wird hochgeladen, nichts verlässt den Tab, was zählt, wenn die Seite, die Sie aufarbeiten, API-Schlüssel, interne Hostnamen oder Kundendaten enthält, die Sie keinem Drittanbieterdienst zuschicken würden.
Das Werkzeug arbeitet in zwei Richtungen und beantwortet zwei unterschiedliche Fragen. Der Format-Modus fragt: Wie sieht diese Struktur aus, wenn die Leerraumzeichen ehrlich sind? Der Minify-Modus fragt: Wie klein darf diese Datei werden, ohne dass sich ein einziges Verhalten ändert? Der Rest dieses Führers erklärt, wie beide Durchgänge arbeiten, was mit einer realen Seite von 458 Zeichen in jedem Modus passiert, welche Teile des Dokuments der Minifizierer strikt nicht antastet und welche er löscht, wie die Einrückungs-Einstellung und die Liste der Inline-Elemente die Ausgabe formen, und wo dieses Werkzeug im Verhältnis zu den anderen Formatier-Werkzeugen der Sammlung steht.
So funktioniert ein HTML-Formatter: zwei Modi, ein Einfügen
Beide Modi lesen dieselbe Eingabe-Zeichenfolge und schreiben ein Ergebnis im Klartext in das Ausgabefeld; der Unterschied ist die angewendete Transformation. Der Format-Modus übergibt das Mark-up dem HTML-Engine von js-beautify mit einem festen Optionssatz: Einrückung mit zwei oder vier Leerzeichen, keine Zeilenumbruch-Länge, kein Zeilenumbruch am Ende, keine Einrückung innerhalb von Inline-Elementen, und eine Liste von Elementen, deren Inhalt nie über Zeilen verteilt wird. Der Minify-Modus fährt ein eigens gebautes Pipeline-Verfahren: Zuerst hebt er jedes script-, textarea- und pre-Block aus dem Dokument aus und legt es beiseite, dann entfernt er HTML-Kommentare, klappt jede Leerraum-Folge auf ein einzelnes Leerzeichen zusammen, löscht die Leerzeichen an den Nahtstellen zwischen Tags und setzt die geschützten Blöcke anschließend Byte für Byte zurück.
Diese Reihenfolge ist das gesamte Design. Leerraum zusammenzuklappen ist für Mark-up sicher und sogar für das CSS innerhalb einer style-Tag, denn in beiden Sprachen bedeutet eine Folge von Leerzeichen und Zeilenumbrüchen dasselbe wie ein einzelnes Leerzeichen. Innerhalb einer pre-Tag ist es nicht sicher, weil dort der Leerraum selbst der Inhalt ist, und auch nicht sicher innerhalb von script, wo der Minifizierer Sätze nur allzu gerne zusammenkleben würde. Erst extrahieren, dann zurücksetzen erlaubt aggressive Durchgänge über den restlichen Teil des Dokuments, während diese drei Regionen exakt so herauskommen wie sie hineingegangen sind, Zeilenumbrüche inklusive.
Der Standardfall: Eine Seite von 458 Zeichen wird zu einer Zeile von 281
Nehmen Sie eine von Hand geschriebene Seite: ein Doctype, ein Head mit Charset, ein Titel, ein kleiner style-Block und ein Body mit einer Karte, die eine Überschrift, einen Absatz und einen Button enthält. So geschrieben, wie Menschen es tatsächlich schreiben, mit der Einrückung, die man tippen würde, und einem übrig gebliebenen Entwurfskommentar, umfasst sie 458 Zeichen auf 28 Zeilen. Fahren Sie sie mit dem Format-Modus und die Seite kommt mit 390 Zeichen auf 27 Zeilen zurück: der übermäßig eingerückte Titel und die Überschrift rücken auf ihre eigenen Zeilen, die Struktur wird neu auf einen konstanten Rhythmus von zwei Leerzeichen verankert, und der Entwurfskommentar bleibt an seinem Ort. Wenn der Standard Ihres Projekts vier Leerzeichen sind, liefert derselbe Durchgang ein Dokument mit derselben Zeilenzahl und breiterer Einrückung.
Fahren Sie dieselbe Seite von 458 Zeichen stattdessen mit dem Minify-Modus, und das Ergebnis sind 281 Zeichen auf einer einzigen Zeile, eine Reduktion um 38,6 Prozent. Der Entwurfskommentar ist fort, die Einrückung ist fort, die Leerzeichen zwischen den Tags sind fort, und was übrig bleibt, ist dasselbe Dokument: gleiche Elemente, gleiche Attribute, gleicher Text, gleiches CSS. Wenn Sie die Werte vor und nach dem Durchgang nebeneinander sehen wollen, ohne die Rechnung von Hand zu machen, liest der Zeichenzähler und -Analyseur die Länge eines beliebigen Feldes und macht die Ersparnis zu einer Zahl, die Sie in einem Pull Request zitieren können.
Was die Minifizierung schützt und was sie entfernt
Drei Blocktypen werden vor jeder Kompaktion aus dem Dokument gehoben: script, textarea und pre. Eine Seite, die ein script mit zwei Zuweisungen enthält, jeweils auf ihrer eigenen Zeile, kommt aus der Minifizierung mit beiden Zeilenumbrüchen intact heraus, denn der gesamte Block, vom öffnenden bis zum schließenden Tag, wandert unangetastet in die Ausgabe. Ein pre-Block, der auf doppelte Leerzeichen und Zeilenumbrüche angewiesen ist, um als Code-Liste zu rendern, behält jedes einzelne davon. Der Schutz ist Byte für Byte, nicht Zeile für Zeile, er gilt daher auch für Leerraum, der versehentlich aussieht, aber Last trägt, etwa die Leerzeichen, die ein Inline-Element daran hindern, mit seinem Nachbarn zu verschmelzen.
Der Schutz ist eine Grenze, kein Ziel. Das JavaScript innerhalb eines geschützten Blocks ist vor dem HTML-Durchgang sicher, und das ist die gesamte Zusage, die der HTML-Durchgang leisten kann: Echte JavaScript-Minifizierung ist eine Syntax-Frage, bei der tote Sätze, überflüssige Klammern und sichere Umbenennungen von Bezeichnern gelöscht werden dürfen, und das erledigt der JavaScript-Formatierer & Minifizierer mit einer Engine, die den Code analysiert, statt Muster zu vergleichen. Die style-Tag steht auf der anderen Seite der Grenze: Ihr CSS ist nicht geschützt, erhält den Leerraum-Durchgang, die Regeln bleiben erhalten, die Abstände schrumpfen, und das Ergebnis ist weiterhin gültiges CSS. Wenn das Stylesheet einen tieferen Durchgang verdient, übernimmt der CSS-Minifizierer, mit einer Engine, die weiß, wo ein Leerzeichen zwischen Selektor und Deklaration Last trägt und wo es reines Rauschen ist.
Alles außerhalb dieser Blöcke erhält die volle Behandlung, und zwei Details lohnen ein Wissen. HTML-Kommentare werden glatt gelöscht, und der Durchgang führt die Kommentar-Entfernung zweimal aus, einmal vor und einmal nach dem Leerraum-Zusammenklappen, weil das Zusammenklappen zwei halbe Kommentare zu einem einzigen zusammenführen kann, der nur in der zusammengeklappten Form existiert. Und die Leerzeichen an den Tag-Nahtstellen, die Lücken zwischen einem schließenden und dem nächsten öffnenden Eckzeichen, verschwinden, sodass die Ausgabe eine ununterbrochene Zeile aus Winkeln ist. Ein zu erwartendes Verhalten: Dort, wo ein geschützter Block im Fluss saß, kann ein einzelnes Leerzeichen an seiner Stelle verbleiben, weil das Zusammenklappen um einen Platzhalter herum erfolgte, nicht um das eigentliche Tag. Es bricht nichts; die Datei ist weiterhin gültig, nur an dieser Stelle ist sie nicht ganz so dicht wie der Rest der Zeile.
Format-Modus: Einrückung, Zeilenumbruch und die Inline-Element-Liste
Der Formatierer bietet genau eine Einstellung, die die meisten Nutzer ändern, und das ist die Einrückungs-Tiefe: zwei Leerzeichen als Standard, vier als Alternative. Auf dem Beispiel von 197 Zeichen und fünf Zeilen mit einem Kommentar und einem kleinen script liefert der Durchgang mit zwei Leerzeichen 244 Zeichen auf 18 Zeilen, und der Durchgang mit vier Leerzeichen liefert dieselben 18 Zeilen mit 278 Zeichen. Gleiche Struktur, gleiche Zeilenzahl, mehr horizontaler Raum; die Wahl ist eine Team-Konvention, keine Frage der Korrektheit. Der Zeilenumbruch ist bewusst deaktiviert, damit eine lange Attribut-Liste auf einer Zeile bleibt, statt an einer willkürlichen Spalte gebrochen zu werden, und die Ausgabe endet genau dort, wo das letzte Tag endet, ohne dass ein Zeilenumbruch angehängt wird.
Die feinere Einstellung ist die Liste der als Inline behandelten Elemente: a, span, td, th, small, pre und code. Für diese Tags verweigert die Engine, die Zeile zwischen öffnender und schließender Klammer zu brechen, sodass ein Link, der ein Wort mitten im Satz umschließt, auf einer Zeile bleibt, und eine Tabellenzelle ihren Inhalt nicht über die ganze Seite verteilt. Genau diese Liste ist der Grund, warum die formatierte Ausgabe einer textlastigen Seite so wirkt, als hätten Sie sie von Hand eingerückt: Blockelemente stapeln sich, Inline-Elemente fließen, und nichts mitten im Satz bekommt einen Zeilenumbruch angedrängt.
Nachbargemächte: JSON, XML und der Platz jedes Formatters
HTML ist das nachsichtigste der Mark-up-Sprachen, und genau deshalb wird sein Leerraum am meisten missbraucht. Eine JSON-Nutzlast hingegen bricht in dem Moment, in dem ein Komma zu viel oder ein Leerzeichen am Ende einschleicht, daher hat sie ein eigenes Werkzeug mit einem Validator, der Zeile und Grund benennt: Der JSON-Formatierer liest dieselbe Art eingefügten Blobs und liefert ihn entweder hübsch gedruckt oder abgewiesen, der richtige Begleiter, wenn das HTML, das Sie aufarbeiten, ein Konfigurationsobjekt in einem script-Tag einbettet. XML ist der strengerer Cousin, bei dem eine nicht passende Klammer ein harter Fehler und keine Vermutung des Browsers ist, und der XML-Formatierer behandelt diese Familie von Dokumenten mit demselben Format-zuzüglich-Minify-Muster.
Die Gliederung hat den Sinn, dass jedes Format eine Engine bekommt, die seine Sprache wirklich spricht: eine HTML-Umstrukturierung für das Dokument, eine CSS-verstehende Engine für die Stylesheets und einen JS-Parser für die Skripte. Alle vier Werkzeuge über eine einzige Seite zu fahren ist dieselbe Arbeitsteilung, die ein Build-System mit seiner Werkzeugkette vornimmt, nur ohne den Build: das Dokument formatieren, die Nutzlasten minimieren, das Ergebnis veröffentlichen. Der HTML-Formatter ist das Stück, das im Ganzen die Struktur lesbar hält, und genau das ist der Teil, den ein generischer Minifizierer zuerst verdirbt, weil er die Dateigröße optimiert, während Sie noch in der Bearbeitung sind.
Das Ergebnis lesen, bevor es online geht
Das Ausgabefeld ist die gesamte Prüfungsfläche, es lohnt sich also, es so zu lesen wie ein Prüfer. Im Format-Modus zuerst die Struktur ansehen: Nesten sich die Blöcke so, wie erwartet, hält die Inline-Element-Liste den Text lesbar, und gibt es ein Element, das der Rhythmus von zwei Leerzeichen schwerer zu folgen macht? Der Kommentar, den die Minifizierung löscht, ist der einzige Punkt, an dem sich die beiden Modi darüber uneins sind, was Ihre Datei enthält, und wenn dieser Kommentar für die nächste Person Last trug, ist die Version des Format-Modus die zu behaltende.
Im Minify-Modus ist die Prüfung kürzer und mechanischer. Die Datei sollte eine Zeile sein, die Tags sollten unmittelbar aneinander liegen, und die geschützten Regionen sollten überleben: Öffnen Sie die Ausgabe, finden Sie das script und bestätigen Sie, dass die Zeilenumbrüche noch da sind. Wenn Sie die Seite als Klartext statt als Mark-up benötigen, entfernt der HTML zu Text Konverter die Tags und liefert die Lesesicht zurück, der richtige Zug, wenn das Ergebnis ein Einfügen in ein Dokument und kein Deployment ist. Und wenn die Konfiguration, die die Seite antreibt, in einer YAML-Datei neben dem Mark-up liegt, wendet der YAML-Formatierer auf diese Datei dasselbe Verfahren an. Einfügen, Modus wählen, Ausgabe lesen, herauskopieren: Die gesamte Schleife bleibt im Tab, der die Datei besitzt, von Anfang bis Ende.