mdjs vorgestellt

mdjs: Interaktive Demos mit Markdown und Javascript schreiben

mdjs: Interaktive Demos mit Markdown und Javascript schreiben

mdjs vorgestellt

mdjs: Interaktive Demos mit Markdown und Javascript schreiben


Ausführbares JavaScript in Markdown integrieren: Das macht mdjs möglich! Entwickler Thomas Allmer gibt einen praktischen Einblick darin, was das ermöglicht und wie es funktioniert.

Jeder gemeinsam genutzte Code sollte über eine schriftliche Dokumentation verfügen, aus der hervorgeht, wofür er verwendet werden kann und welche Idee dahinter steckt. Benutzer sollten zumindest in der Lage sein, auf hohem Niveau zu verstehen, was sie benutzen, wofür sie es benutzen und warum.

Im Web stehen uns viele, viele verschiedene Arten zum Schreiben von Dokumentationen zur Verfügung. Eine Sache haben jedoch fast alle gemeinsam: Dass sie sich auf Markdown oder eine Variation davon stützen. Und das ist keine Überraschung, denn Markdown wird praktisch überall unterstützt (VS Code, Atom, GitHub, GitLab, Dev.to, npm, usw.).

Markdown: Verwendung in verschiedenen Tools

Mit Tools, die nicht im Browser laufen
In diesem Fall werden meist Code-Snippets zur Verfügung gestellt, die die Benutzer in ihren eigenen Projekten ausführen müssen. Dafür funktionieren traditionelle statische Website-Generatoren wie Docusaurus, VuePress, Gatsby usw. hervorragend. Alle haben volle Unterstützung für Markdown und ermöglichen es, auf einfache Weise schöne Dokumentationsseiten mit Code-Snippets/Highlighting und mehr zu erstellen.

Und offen gesagt, wenn das Ihr Anwendungsfall ist, sollte fast alles, was Sie brauchen, mit diesen Werkzeugen möglich sein, solange Sie sich mit dem Ökosystem/Framework wohl fühlen.

Für (visuelle) Komponenten, die im Browser laufen
Hierbei erwarten die Benutzer wahrscheinlich eine Live-Demo, um all die verschiedenen Optionen Ihrer Komponente in Aktion zu sehen. Ein reines Markdown reicht also in der Regel nicht aus, da wir nun tatsächlich Code ausführen und unsere Arbeitskomponente irgendwie in unsere Dokumentation einfügen wollen. Dies würde eine spezielle Handhabung für jedes Framework erfordern.

Mit Vue
Für Vue können Sie beispielsweise VuePress verwenden, das alle Vue-Komponenten in einem bestimmten Ordner automatisch registriert. Dann können Sie sie als normale HTML-Tags verwenden, da Markdown HTML unterstützt.

  • unterstützt Vue-Komponenten und bringt einen „magischen“ Import dafür mit
  • Kein Support für generisches JavaScript oder die Weitergabe von Properties an Komponenten

Für React
Für React können Sie MDX verwenden, das Markdown mit JSX-Unterstützung erweitert. MDX ist über verschiedene Tools wie Gatsby, Docz, Storybook usw. verfügbar.

import { Chart } from '../components/chart'

# Here’s a chart

The chart is rendered inside our MDX document.

  • Unterstützt import/export in JavaScript
  • Schickt alles durch JSX
  • Sieht auf GitHub nicht gut aus; benötigt spezielle Tools im Editor um Highlighting zu ermöglichen

Grenzen
Allen diesen spezialisierten Werkzeugen ist gemeinsam, dass sie ein spezifisches Build-Tooling-Setup benötigen, um zu funktionieren. Für Web Components wird nichts davon tatsächlich benötigt. Markdown erlaubt bereits HTML. Der einzige fehlende Teil ist, wie eine Web Component durch JavaScript geladen werden kann.

Markdown mit JavaScript (mdjs) vorgestellt
Die primären Ziele sind:

  • Komplexität minimieren
  • Progressive Enhancement verfolgen
  • nah an einer gültigen Markdown-Syntax bleiben
  • Code-Highlighting in Editoren ohne zusätzliche Tools
  • soll gut auf GitHub/GitLab/in jedem Tool zum Management von Quellcode aussehen.

Der Grundgedanke scheint fast zu einfach, um wahr zu sein. Wir erweitern einen Code Fence Block mit zusätzlichen Metadaten js script:

```js script
import './my-component.js';

This is my component

Und das war’s!

Genug der Worte: Hier geht’s zur bearbeitungsfähigen Live-Demo.

Wie funktioniert das?

mdjs hakt sich bei remark ein und extrahiert alle Blöcke daraus, die mit js getagged sind. HTML und JavaScript sind am Ende separat verfügbar.

Der Code kann dann mit jedem Tool kombiniert und verarbeitet werden, um eine richtige Dokumentationsseite zu erstellen.

  1. js script extrahieren und vom Markdown trennen
  2. Markdown rendern
  3. HTML und JavaScript zur Verfügung stellen

script transformation

Hier ist ein Link zu der Animation als Slides.

Das ist an sich schon mächtig genug, um JavaScript direkt zu integrieren und Web Components mit Attributen zu rendern.

mdjs mit Demo-Format erweitern
Da wir nun JavaScript innerhalb unseres Markdowns ausführen können, öffnet dies die Tür für fortgeschrittenere Funktionen.

Unser erster Schritt ist die Erstellung eines weiteren erweiterten JavaScript-Codeblocks, nämlich <code>js story</code>. Von diesem Codeblock aus können Sie eine Funktion exportieren, die bei Bedarf ausgeführt werden kann:

```js script
import './my-component.js';

This is my component

export const demo = () => ``

Wenn Sie eine Umrandung und einen Button zum Ein-/Ausblenden des eigentlichen Quellcodes hinzufügen möchten, können Sie js preview-story verwenden.

Was Sie erhalten, sieht in etwa so aus:

  1. js script extrahieren und vom Markdown trennen
  2. js story und js preview-story extrahieren und vom Markdown trennen
  3. Den Platzhalter oder mdjs-preview an die richtige Stelle einsetzen
  4. Markdown rendern
  5. HTML, JavaScript und Stories zur Verfügung stellen

Das sind alle Informationen, die wir brauchen um aus reinem Markdown Seiten zu erzeugen, die vollständig für JavaScript und Demos geeignet sind.

Standardmäßig geht mdjs einen kleinen Schritt weiter, indem es ein richtiges Template-System unterstützt – nämlich lit-html.

```js script
import './demo-wc-card.js';
import { html } from 'lit-html';

This is my component

export const demo = () => html`
  
`;

story transformation

Hier kann die Animation als Slides gefunden werden, und hier ist ein weiterer Playground, der eine vollständige Dokumentationsseite simuliert.

mdjs Standard Docs-Seite
Sobald alle Meta-Informationen verfügbar sind, kann man eine spezifische Doc-Seite rendern. Am Ende wird dazu der folgende Code erzeugt, der die Demo-Funktion einer Web Component zuweist:

const stories = [{ key: 'demo', story: demo, code: demo }];
for (const story of stories) {
  const storyEl = rootNode.querySelector(`[mdjs-story-name="${story.key}"]`);
  storyEl.story = story.story;
  storyEl.code = story.code;
}

Das findet alles unter der Haube statt.

Wo kann man mdjs verwenden?

Lokal via es-dev-server
Jetzt zeige ich, wie man Markdown-Ansicht im Stil von GitHub für alle lokalen Markdown-Dateien erstellen kann, inklusive Live-Demos.

• es-dev-server als Dependency installieren, indem man npm i -D es-dev-server ausführt
• Folgendes Skript zur package.json hinzufügen:

	"scripts": {
	  "start": "es-dev-server",
	}

es-dev-server.config.js im Root des Repos erstellen:

const { mdjsTransformer } = require('@mdjs/core');

module.exports = {
  nodeResolve: true,
  open: 'README.md',
  watch: true,
  responseTransformers: [mdjsTransformer],
};

Nachdem npm run start ausgeführt wurde, kann man die Live-Dokumentation via http://localhost:8000/README.md aufrufen.

Ein Beispiel-Setup kann man im demo-wc-card-Repo sehen.

Per Storybook verwenden
Wenn man an individuellen Komponenten arbeiten oder eine Liste aller Demos haben möchte, kann man Storybook verwenden.

    • Die Dependency npm i -D @open-wc/demoing-storybook installieren
    • Zur package.json hinzufügen:
      "scripts": {
        "storybook": "start-storybook",
      }
      
      
    • .storybook/main.js anpassen, um Markdown-Dateien zu laden:
      module.exports = {
        stories: ['../README.md', '../docs/**/*.md'],
        esDevServer: {
          nodeResolve: true,
          watch: true,
          open: true,
        },
      };
      
      
    • Jeder Markdown-Datei, die in Storybook angezeigt werden soll, einen Namen geben:
      export default {
        title: 'My Group/My Awesome Component',
      };
      
      

      Und schon funktioniert es. Man muss keine weiteren Änderungen an Dateien vornehmen; ein Plug-in kümmert sich um alles, indem es Markdown-Dateien so konvertiert, dass sie das MDX-Format von Storybook unterstützen.
      Detailliertere Informationen: https://open-wc.org/demoing-storybook/

      Auf GitHub anzeigen
      Da GitHub ja Markdown out of the Box unterstützt, können wir mit mdjs hier noch mehr erreichen.

      Da GitHub das aber nicht direkt unterstützt, ist eine Chrome-Extension nötig: mdjs-viewer.

          • Wollen Sie eine Demo sehen, ohne eine andere Seite zu öffnen? mdjs-viewer!
          • Wollen Sie Beispiele für Issues live abspielen? mdjs-viewer!

      Fast schon schwarze Magie, oder? Wir haben nur eine Chrome-Extension installiert und plötzlich hat GitHub Superkräfte.
      Alles, was man dafür braucht, sind ein paar Markdown-Dateien mit den korrekten Code-Fence-Blocks. Außerdem muss der Code auf unpkg.com hochgeladen und ausgeführt werden.

      Wie funktioniert das?
      Die Erweiterung erkennt, auf welcher GitHub-Seite Sie sich befinden. Wenn sie eine Markdown-Datei oder ein Problem mit mdjs-Code findet,
      fügt sie einen Button „Show Demo“ hinzu, um sie zu aktivieren. Wird dieser geklickt, werden alle benötigten Informationen gesammelt:

      • Das nächstgelegene package.json finden.
      • Lesen der aktuellen Markdown-Datei/den aktuellen Inhalt der Issue.
      • Ersetzen aller reinen Importe durch unpkg.com-Importe.
      • Ersetzen aller relativen Importe durch unpkg.com und den Namen des package.json + relativen Pfad für diesen.
      • Erstellen eines gesicherten Iframes.
      • Absolutes positionieren des Iframes als Überlagerung.
      • Einfügen des JavaScript- und HTML-Codes in den Iframe.
      • Die Schaltfläche wird zu einem Umschalter zum Ein-/Ausblenden des Iframe.

      Einige der Aufgaben sind komplizierter und erfordern einige zusätzliche Arbeit, aber im Wesentlichen ist das alles.
      Damit können Sie Dokumentation mit Live-Beispielen auf GitHub stellen. Sogar Probleme mit Demos, die den tatsächlichen Fehler im Code zeigen, sind möglich. Die Readme-Datei und der Inhalt der Ausgabe bleiben darüber hinaus auch ohne die Erweiterung nützlich.
      Ausführlichere Informationen finden Sie unter https://github.com/open-wc/mdjs-viewer.

      Unterstützt durch webcomponents.dev
      Unterstützt wird mdjs durch diesen nützlichen Online Editor:

      Damit können Dokumentation, Demos und Code direkt im Browser bearbeitet werden.

      Wie im obigen Screenshot zu sehen, kann direkt mit der Dokumentation begonnen werden. Auch kann jede Markdown-Datei oder README.md verwenden werden.

      Alle Demo-Links sind von webcomponents.dev. Probieren Sie es gerne aus!

      Support für mdjs hinzufügen
      Die offizielle Dokumentation findet sich unter https://open-wc.org/mdjs/.

      Fazit

      mdjs ist ein Format, das auf viele verschiedene Arten dargestellt werden kann. Sei es lokal, ein veröffentlichtes Storybook, auf GitHub oder npm, es sieht immer gut aus. Auch wenn es keine direkte Unterstützung dafür gibt, wird es durch diese progressive Erweiterung interaktiv mit Demos.

      Und damit viel Spaß beim Schreiben ihrer Dokumentationen für Ihre Komponenten!

      Ausblick

      Ein separates GitHub-Repo erstellen (möglicherweise auch eine Gruppe)
      • Eine eigene Homepage erstellen
      • Der Standardframe für die Story Preview sollte etwas hübscher aussehen
      • Unterstützung mehrerer Renderer – Diskussion zum Thema
      • Hervorhebung von Code-Snippets
      • Mehr Helfer für den Einsatz in Stories
      • … (zögert bitte nicht, Fragen innerhalb der entsprechenden Projekte zu stellen)

Thomas Allmer ist Softwareentwickler und Gründer von Open Web Components. Er ist ein Verfächter von „buildless development“ und arbeitet gerne so eng wie Möglich mit „the Platform“ (Browser). Er genießt open source und ist außerdem ein core contributor für ING’s Lion web components.


Weitere Artikel zu diesem Thema