Web Component für einen Code Block

Avatar of Chris Coyier
Chris Coyier am

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

Darauf kommen wir noch zurück, aber zuerst eine langatmige Einleitung.

Ich bin mir immer noch nicht sicher, wann eine gute Zeit ist, native Web Components zu verwenden. Das Templating ist nicht besonders robust, was mich nicht anspricht. Es gibt kein State Management, und ich mag es, standardmäßige Wege dafür zu haben. Wenn ich sowieso eine andere Bibliothek für Komponenten verwende, bleibe ich wohl einfach dabei. Also, im Moment sieht meine Checkliste etwa so aus:

  • Kein anderes JavaScript-Framework verwenden, das Komponenten hat
  • Die Templating-Anforderungen sind nicht besonders komplex
  • Keine besonders performante Neurendering benötigt
  • Kein State Management benötigt

Ich bin sicher, dass es Tools gibt, die bei diesen Dingen und mehr helfen (die devMode-Episode mit einigen Leuten von Stencil war gut), aber wenn ich mich mit Tools beschäftige, wäre ich noch mehr versucht, ein Framework zu wählen, und wahrscheinlich nicht ein Framework plus ein weiteres Ding mit viel Überschneidung.

Die Gründe, warum ich versucht bin, native Web Components zu verwenden, sind:

  • Sie sind nativ. Keine Downloads von Frameworks.
  • Der Shadow DOM ist eine echte Kapselung auf eine Weise, wie es ein Framework wirklich nicht kann.
  • Ich kann mein eigenes HTML-Element erstellen, das ich in HTML verwende, mit meinem eigenen API-Design.

Es scheint irgendwie der Sweet Spot für native Web Components zu sein: Designsystem-Komponenten. Man baut seine eigene kleine API für die Komponenten in seinem System, und Leute können sie auf eine Weise verwenden, die viel sicherer ist, als einfach diesen HTML-Block kopieren und einfügen. Und ich nehme an, wenn Verbraucher des Systems ein Framework mitbringen wollten, könnten sie das tun.

Man kann also so etwas verwenden wie <our-tabs active-tab="3"> anstelle von <div class="tabs"> ... <a href="#3" class="tab-is-active">. Das Refactoring der Komponenten wird definitiv viel einfacher, da sich Änderungen überall durchsickern.

Ich habe sie hier auf CSS-Tricks für unsere <circle-text> Komponente verwendet. Sie nimmt den Radius als Parameter und den Inhalt über, ähm, Inhalt, und gibt ein <svg> aus, das den Trick macht. Sie hat uns eine schöne API für die Autorenschaft gegeben, die die Komplexität abstrahiert hat.

So!

Mir kam der Gedanke, dass ein "Code-Block" ein schöner Anwendungsfall für eine Web Component sein könnte.

  • Die API wäre dafür schön, da man Attribute für nützliche Dinge haben könnte und den Code selbst als Inhalt (was ein großartiger Fallback ist).
  • Es braucht eigentlich keinen Zustand.
  • Syntax-Hervorhebung ist ein großer, unhandlicher CSS-Block, daher wäre es ziemlich cool, das im Shadow DOM zu isolieren.
  • Es könnte nützliche Funktionen wie eine "Klick zum Kopieren"-Schaltfläche haben, die Leute gerne hätten.

Alles in allem könnte es sich wie eine Komponente anfühlen, für die man denkt: Ja, das könnte ich verwenden.

Das ist wahrscheinlich noch nicht wirklich produktionsreif (zum einen ist es noch nicht auf npm oder so), aber hier ist, wo ich bisher bin

Hier ist ein Gedanken-Dump!

  • Was machst du, wenn eine Komponente von einer Drittanbieter-Bibliothek abhängt? Die Syntax-Hervorhebung hier erfolgt mit Prism.js. Um sie besser zu isolieren, könnte man wohl die ganze Bibliothek irgendwo hineinkopieren, aber das erscheint albern. Vielleicht dokumentiert man es einfach?
  • Das Styling von Web Components scheint noch keine gute Geschichte zu haben, obwohl der Shadow DOM cool und nützlich ist.
  • Das Einbinden von vorformatiertem Text zur Verwendung in einem Template ist super seltsam. Ich bin sicher, dass es möglich ist, dies zu tun, ohne ein <pre>-Tag innerhalb des benutzerdefinierten Elements zu benötigen, aber es ist offensichtlich viel einfacher, wenn man den Inhalt aus dem <pre> nimmt. Macht die API hier nur einen winzigen Tick weniger freundlich (da ich lieber das <code-block> allein verwenden würde).
  • Ich frage mich, was eine gute Praxis für die Weitergabe von Attributen ist, die eine andere Bibliothek benötigt. Zum Beispiel ist data-lang="CSS" in Ordnung (fühlt sich besser an) und wird dann in der Vorlage in class="language-css" umgewandelt, weil Prism das will? Oder ist es eine bessere Praxis, Attribute einfach so weiterzugeben, wie sie sind? (Ich habe mich für Letzteres entschieden.)
  • Leute beschweren sich, dass es in nativen Web Components keine wirklich "Lifecycle Methods" gibt, aber zumindest hat man eine: wenn das Ding gerendert wird: connectedCallback. Also, ich nehme an, man sollte die gesamte Manipulation von HTML und so weiter durchführen, bevor man das endgültige shadowRoot.appendChild(node); macht. Das mache ich hier nicht, sondern lasse Prism über den gesamten shadowRoot laufen, nachdem er angehängt wurde. Es schien einfach so zu funktionieren. Ich stelle mir vor, dass es wahrscheinlich besser und möglich ist, dies im Voraus zu tun, anstatt all die Neuanzeigen zuzulassen, die durch das Einfügen von Spans usw. verursacht werden.
  • Der Sinn der Sache ist eine schöne API. Mir scheint, dass es schöner wäre, wenn man unescaped HTML zum Hervorheben einfügen könnte und es für einen selbst escapen würde. Aber das würde dazu führen, dass der Fallback dieses HTML rendert, was schlecht (oder sogar theoretisch unsicher) sein könnte. Was ist eine gute Lösung dafür? Vielleicht den HTML-Code in HTML-Kommentare setzen und prüfen, ob <!-- der Anfang des Inhalts ist und das als Sondersituation behandeln?

Jedenfalls, wenn du es forken oder etwas Besseres damit machen willst, sag Bescheid. Vielleicht können wir es irgendwann auf npm oder so veröffentlichen. Wir müssen sehen, wie nützlich die Leute es finden.