@webmate-studio/render-core
v0.1.0
Published
Reiner Renderkern: Template + Props → HTML. Läuft unverändert im Browser und in Node.
Downloads
105
Readme
@webmate-studio/render-core
Ein Renderkern für alle Umgebungen: CMS-Vorschau, Website-Build, wm dev.
Warum es das gibt
Bisher existierte die Renderlogik zweimal — einmal für den Browser, einmal für den Build Service. Der Dateikopf der Build-Fassung behauptete:
Same code as browser version — guarantees preview === build
Das stimmte nicht. Es waren zwei Implementierungen, von Hand synchron gehalten. Zwei Implementierungen können nicht garantiert übereinstimmen, sie können nur gerade zufällig übereinstimmen. Genau daraus sind die Abweichungen zwischen Vorschau und veröffentlichter Seite entstanden.
Der einzige Weg, „Vorschau = veröffentlichte Seite" zu einer Zusage statt einer Hoffnung zu machen, ist dieselbe Datei an beiden Stellen.
Die Regel
Dieses Paket macht kein I/O. Kein fetch, kein Dateisystem, kein DOM.
Daten hinein, HTML heraus.
Dadurch läuft dieselbe Datei im Browser des Redakteurs und im Build-Worker. Alles Umgebungsabhängige wird hineingereicht:
| | |
|---|---|
| expressionEngine | Ausdrucksauswertung (@webmate-studio/builder) |
| processMarkdownProps | Markdown → SafeHtml |
| resolveApiUrls | api-url-Props über den Component-Proxy |
Erzwungen wird das durch npm run check:purity, nicht durch Disziplin. Die
Prüfung bricht den Build, sobald der Kern node:* importiert oder document,
window, process.env oder fetch anfasst.
Was Netzzugriff braucht — Blöcke, Formulare, Design Tokens — gehört in die
Ladeschicht davor. Im Build Service ist das content-prefetch.js.
Verwendung
import { ComponentRenderer } from '@webmate-studio/render-core';
import expressionEngine from '@webmate-studio/builder/src/expression-evaluator.js';
import { processMarkdownProps, resolveApiUrls } from '@webmate-studio/builder';
const renderer = new ComponentRenderer({ expressionEngine, processMarkdownProps, resolveApiUrls });
const html = renderer.render(template, props, propSchema, {
proxyBaseUrl: 'https://app.example.com/api/component-proxy',
componentMetadata
});
// Fehlgeschlagene Ausdrücke rendern als leer — hier erfährt man, warum.
const diagnosen = renderer.drainDiagnostics();Prüfen
npm testReinheitsprüfung plus 36 Tests: Parser-Robustheit (neun Eingaben, bei denen die bisherige Implementierung in einer Endlosschleife hängt), Baumgestalt, Maskierungsvertrag, Blöcke, Direktiven.
Golden Files
Die eigentliche Gleichwertigkeitsprüfung liegt außerhalb dieses Repos:
Golden-File-Harness/ mit 237 Referenzausgaben aus 79 echten Komponenten,
8 Seitenmontagen und dem Gleichwertigkeitsnachweis für den Vorlader.
Sie liegen dort, weil sie sich aus Kundeninhalten ableiten und nicht in den Quellcode gehören. Im Repo laufen nur Tests, die ohne Kundendaten auskommen.
cd ../../../Golden-File-Harness/_harness && node alles.mjsVersionierung
Konsumenten pinnen exakt, nicht mit Caret. Eine Nebenversion, die in der Vorschau ankommt und im Build nicht, ist genau der Fehler, den dieses Paket abstellen soll — und er ist unsichtbar, wenn er passiert.
Offene Punkte im Rendervertrag
Aus der bestehenden Implementierung übernommen, weil eine Änderung die Ausgabe aller bestehenden Seiten verändern würde. Festgehalten in den Tests, damit es niemand „aufräumt" — und damit es sichtbar bleibt:
- Maskierung ist asymmetrisch. Im Text nur
<und>, das&bleibt. In Attributwerten&und", nicht aber<. falserendert als leer,0rendert. Svelte rendert beides.- Leere Attributwerte bleiben stehen.
title=""statt weggelassen — für Screenreader ein Unterschied. - HTML-Tags sind flach.
<p>{x}</p>ergibt drei Geschwister; nur{#if}/{#each}bilden echte Verschachtelung. Der Renderer schreibt Tags durch, statt HTML zu verstehen.
