API-Referenz
Verso exportiert sieben Funktionen und drei Fehlerklassen. Typdeklarationen liegen dem Paket bei; sie sind von Hand geschrieben und werden in der CI gegen die Implementierung geprüft.
compile()
Kompiliert ein Template aus einem String und gibt die Renderfunktion zurück. Wirft VersoSyntaxError, wenn sich der Quelltext nicht parsen lässt.
import { compile } from 'verso';
const greet = compile('Hello, {{name}}!');
greet({ name: 'Ada' }); // 'Hello, Ada!'
CompileOptions
| Option | Typ | Standard | Beschreibung |
|---|---|---|---|
name | string | '(anonymous)' | Erscheint in Fehlern und Stackframes |
strict | boolean | false | Bei fehlenden Eigenschaften eine Ausnahme werfen, statt einen leeren String zu rendern |
allowRaw | boolean | true | {{{ }}} erlauben; auf false setzen, um unescapte Ausgabe im ganzen Projekt zu verbieten |
filters | Record<string, Function> | {} | Zusätzliche Filter, die über die eingebauten gelegt werden |
resolve | (path, from) => string | Node-Auflösung | Eigene Auflösung von Partials |
cache | boolean | true | Kompilierte Partials innerhalb eines Prozesses wiederverwenden |
trimBlocks | boolean | false | Den Zeilenumbruch nach einem Block-Tag entfernen |
compileFile()
Liest eine Datei, löst ihre Partials relativ zu ihr auf und kompiliert. Das zurückgegebene Promise wird mit VersoSyntaxError oder einem Dateisystemfehler abgelehnt.
const page = await compileFile('views/page.vs', { strict: true });
Kompilierte Templates werden nach absolutem Pfad und mtime gecacht. Setzen Sie in der Entwicklung cache: false oder rufen Sie clearCache() aus Ihrem Watcher auf.
TemplateFn
Der Rückgabewert von compile(). Synchron, es sei denn, das Template enthält #defer — dann gibt es ein Promise zurück.
| Eigenschaft | Typ | Beschreibung |
|---|---|---|
template.source | string | Erzeugtes JavaScript, nützlich zum Debuggen und zum Schreiben auf die Platte |
template.name | string | Der beim Kompilieren vergebene Name |
template.deps | string[] | Absolute Pfade aller erreichten Partials, für den Watch-Modus |
template.async | boolean | true, wenn das Template verzögerte Blöcke enthält |
RenderOptions
| Option | Typ | Beschreibung |
|---|---|---|
locals | object | Werte, erreichbar als {{@name}} |
signal | AbortSignal | Bricht verzögerte Blöcke ab, die noch nicht fertig sind |
onError | (err, node) => string | Ersetzt einen fehlschlagenden Block durch einen Ersatz-String, statt eine Ausnahme zu werfen |
renderToStream()
Gibt einen Node.js-Readable im objektfreien String-Modus zurück. Blöcke der obersten Ebene werden ausgegeben, sobald sie fertig sind; verzögerte Blöcke werden mit einem kleinen Inline-Skript angehängt, das sie an ihren Platz verschiebt.
import { compileFile, renderToStream } from 'verso';
const report = await compileFile('views/report.vs');
server.get('/report/:id', (req, res) => {
const controller = new AbortController();
res.on('close', () => controller.abort());
res.type('html');
renderToStream(report, { id: req.params.id }, { signal: controller.signal })
.on('error', (err) => { res.destroy(err); })
.pipe(res);
});
Sobald Bytes den Server verlassen haben, können Sie keinen 500er mehr senden. Behandeln Sie das mit onError, das den fehlschlagenden Block durch einen Ersatz ersetzt und den Stream am Leben hält.
raw()
Markiert einen String als bereits sicheres HTML, damit die Interpolation ihn nicht escaped. Der einzige Weg, wie ein Filter oder ein Datenwert ohne dreifache Klammern Markup ausgeben kann.
import { raw } from 'verso';
page({ badge: raw('<span class="beta">beta</span>') });
Behandeln Sie jeden Aufruf von raw() als Sicherheitsentscheidung. Die Lint-Regel des Repositorys verlangt einen Kommentar in der Zeile darüber; diese Regel in Ihr Projekt zu übernehmen, kostet nichts.
registerFilter() und clearCache()
Fügt einen Filter global hinzu, für jedes danach kompilierte Template. Bevorzugen Sie die Option filters pro Kompilierung: Globale Registrierung macht Templates von der Ladereihenfolge der Module abhängig, was mühsam zu debuggen ist.
Entfernt einen Eintrag oder, ohne Argumente aufgerufen, den ganzen Kompilier-Cache.
Fehlerklassen
| Klasse | Geworfen, wenn | Zusätzliche Felder |
|---|---|---|
VersoSyntaxError | ein Template sich nicht parsen lässt | file, line, column, frame |
VersoLookupError | im strikten Modus eine Eigenschaft fehlt | path, file, line |
VersoRenderError | ein Filter oder verzögerter Block eine Ausnahme wirft | cause, node, file, line |
Alle drei erweitern Error und setzen name auf den Klassennamen. Das Feld frame enthält einen zweizeiligen Auszug mit einem Caret unter dem fehlerhaften Token:
VersoSyntaxError: unexpected '/each', expected '/if'
views/list.vs:14:7
13 | {{#if item.visible}}
14 | {{/each}}
| ^
TypeScript
Deklarationen sind enthalten. TemplateFn ist generisch über die Form der Daten, Sie können ein Template also an ein Interface binden:
import type { TemplateFn } from 'verso';
interface ReportData { id: string; rows: Row[] }
const report: TemplateFn<ReportData> =
await compileFile<ReportData>('views/report.vs');
Der Compiler prüft Template-Inhalte nicht gegen den Typ — dafür bräuchte es einen typbewussten Parser, und wir haben uns zweimal dagegen entschieden, einen zu bauen.