Referentie

API-referentie

Verso exporteert zeven functies en drie foutklassen. Typedeclaraties zitten in het pakket; ze zijn met de hand geschreven en worden in de CI tegen de implementatie gecontroleerd.

compile()

compile(source: string, options?: CompileOptions): TemplateFn

Compileert een template vanuit een string en geeft de renderfunctie terug. Gooit VersoSyntaxError als de bron niet te parsen is.

import { compile } from 'verso';

const greet = compile('Hello, {{name}}!');
greet({ name: 'Ada' });  // 'Hello, Ada!'

CompileOptions

OptieTypeStandaardBeschrijving
namestring'(anonymous)'Getoond in fouten en stackframes
strictbooleanfalseEen fout gooien bij ontbrekende eigenschappen in plaats van een lege string te renderen
allowRawbooleantrue{{{ }}} toestaan; zet op false om ongeëscapete uitvoer in het hele project te verbieden
filtersRecord<string, Function>{}Extra filters die over de ingebouwde worden gelegd
resolve(path, from) => stringnode-resolutieEigen resolutie van partials
cachebooleantrueGecompileerde partials hergebruiken binnen één proces
trimBlocksbooleanfalseDe regelovergang na een bloktag weglaten

compileFile()

compileFile(path: string, options?: CompileOptions): Promise<TemplateFn>

Leest een bestand, lost de partials relatief daaraan op en compileert. De teruggegeven promise wordt afgewezen met VersoSyntaxError of een bestandssysteemfout.

const page = await compileFile('views/page.vs', { strict: true });
Caching

Gecompileerde templates worden gecachet op absoluut pad en mtime. Zet tijdens de ontwikkeling cache: false of roep clearCache() aan vanuit je watcher.

TemplateFn

template(data?: object, options?: RenderOptions): string

De waarde die compile() teruggeeft. Synchroon, tenzij het template #defer bevat — dan geeft het een promise terug.

EigenschapTypeBeschrijving
template.sourcestringGegenereerd JavaScript, handig voor debuggen en om naar schijf te schrijven
template.namestringDe naam die bij het compileren is gegeven
template.depsstring[]Absolute paden van elk bereikt partial, voor watch-modus
template.asyncbooleantrue als het template uitgestelde blokken bevat

RenderOptions

OptieTypeBeschrijving
localsobjectWaarden bereikbaar als {{@name}}
signalAbortSignalBreekt uitgestelde blokken af die nog niet klaar zijn
onError(err, node) => stringVervangt een falend blok door een reservestring in plaats van een fout te gooien

renderToStream()

renderToStream(template: TemplateFn, data?: object, options?: RenderOptions): Readable

Geeft een Node.js-Readable terug in objectvrije stringmodus. Blokken op het hoogste niveau worden doorgestuurd zodra ze klaar zijn; uitgestelde blokken worden toegevoegd met een klein inline script dat ze op hun plek zet.

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);
});
Fouten na de eerste flush

Zodra er bytes van de server zijn vertrokken, kun je geen 500 meer sturen. Vang dat op met onError, dat een reserve in de plaats zet van het falende blok en de stream in leven houdt.

raw()

raw(value: string): RawString

Markeert een string als al veilige HTML, zodat interpolatie hem niet escapet. De enige manier waarop een filter of datawaarde markup kan uitvoeren zonder drievoudige accolades.

import { raw } from 'verso';

page({ badge: raw('<span class="beta">beta</span>') });
Reviewregel

Behandel elke aanroep van raw() als een beveiligingsbeslissing. De lintregel van de repository vereist commentaar op de regel erboven; die regel overnemen in je eigen project kost niets.

registerFilter() en clearCache()

registerFilter(name: string, fn: Function): void

Voegt een filter globaal toe, voor elk template dat daarna wordt gecompileerd. Gebruik liever de optie filters per compilatie: globale registratie maakt templates afhankelijk van de laadvolgorde van modules, en dat is lastig te debuggen.

clearCache(path?: string): void

Verwijdert één item, of de hele compileercache als je het zonder argumenten aanroept.

Foutklassen

KlasseGegooid alsExtra velden
VersoSyntaxErrorEen template niet te parsen isfile, line, column, frame
VersoLookupErrorEen eigenschap ontbreekt in strikte moduspath, file, line
VersoRenderErrorEen filter of uitgesteld blok een fout gooitcause, node, file, line

Alle drie breiden Error uit en zetten name op de klassenaam. Het veld frame bevat een fragment van twee regels met een caret onder het foute token:

VersoSyntaxError: unexpected '/each', expected '/if'
  views/list.vs:14:7

  13 |   {{#if item.visible}}
  14 |     {{/each}}
     |       ^

TypeScript

Declaraties zitten erbij. TemplateFn is generiek over de vorm van de data, dus je kunt een template aan een interface koppelen:

import type { TemplateFn } from 'verso';

interface ReportData { id: string; rows: Row[] }

const report: TemplateFn<ReportData> =
  await compileFile<ReportData>('views/report.vs');

De compiler controleert de inhoud van templates niet tegen het type — daarvoor is een typebewuste parser nodig, en we hebben twee keer besloten die niet te bouwen.