Dokumentacja

Dokumentacja API

Verso eksportuje siedem funkcji i trzy klasy błędów. Deklaracje typów są dołączone do pakietu; pisane ręcznie i sprawdzane względem implementacji w CI.

compile()

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

Kompiluje szablon z łańcucha i zwraca funkcję renderującą. Rzuca VersoSyntaxError, jeśli źródła nie da się sparsować.

import { compile } from 'verso';

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

CompileOptions

OpcjaTypDomyślnieOpis
namestring'(anonymous)'Pokazywana w błędach i ramkach stosu
strictbooleanfalseRzucaj wyjątek przy brakujących właściwościach zamiast renderować pusty łańcuch
allowRawbooleantrueZezwalaj na {{{ }}}; ustaw false, aby zakazać nieescapowanego wyjścia w całym projekcie
filtersRecord<string, Function>{}Dodatkowe filtry nakładane na wbudowane
resolve(path, from) => stringrozwiązywanie nodeWłasne rozwiązywanie partiali
cachebooleantruePonowne użycie skompilowanych partiali w obrębie jednego procesu
trimBlocksbooleanfalseUsuń znak nowej linii po znaczniku bloku

compileFile()

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

Czyta plik, rozwiązuje jego partiale względem niego i kompiluje. Zwrócona obietnica jest odrzucana z VersoSyntaxError albo błędem systemu plików.

const page = await compileFile('views/page.vs', { strict: true });
Pamięć podręczna

Skompilowane szablony są cache’owane według ścieżki bezwzględnej i mtime. W trakcie pracy ustaw cache: false albo wywołuj clearCache() z obserwatora plików.

TemplateFn

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

Wartość zwracana przez compile(). Synchroniczna, chyba że szablon zawiera #defer — wtedy zwraca obietnicę.

WłaściwośćTypOpis
template.sourcestringWygenerowany JavaScript, przydatny do debugowania i zapisu na dysk
template.namestringNazwa nadana przy kompilacji
template.depsstring[]Ścieżki bezwzględne wszystkich osiągniętych partiali, dla trybu obserwacji
template.asyncbooleantrue, gdy szablon zawiera odroczone bloki

RenderOptions

OpcjaTypOpis
localsobjectWartości dostępne jako {{@name}}
signalAbortSignalPrzerywa odroczone bloki, które się jeszcze nie zakończyły
onError(err, node) => stringZastępuje błędny blok tekstem zastępczym zamiast rzucać wyjątek

renderToStream()

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

Zwraca Readable Node.js w trybie łańcuchowym bez obiektów. Bloki najwyższego poziomu są wysyłane, gdy się kończą; odroczone bloki są dołączane z małym skryptem inline, który przenosi je na miejsce.

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);
});
Błędy po pierwszym wysłaniu

Gdy bajty opuściły serwer, nie da się już wysłać 500. Obsłuż to przez onError, które podmienia błędny blok na zastępczy i utrzymuje strumień przy życiu.

raw()

raw(value: string): RawString

Oznacza łańcuch jako już bezpieczny HTML, żeby interpolacja go nie escapowała. Jedyny sposób, by filtr lub wartość danych wyemitowały znaczniki bez potrójnych nawiasów.

import { raw } from 'verso';

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

Traktuj każde wywołanie raw() jak decyzję dotyczącą bezpieczeństwa. Reguła lintera w repozytorium wymaga komentarza w linii powyżej; przeniesienie tej reguły do twojego projektu nic nie kosztuje.

registerFilter() i clearCache()

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

Dodaje filtr globalnie, dla każdego szablonu kompilowanego później. Lepiej używać opcji filters dla pojedynczej kompilacji: rejestracja globalna uzależnia szablony od kolejności ładowania modułów, co trudno debugować.

clearCache(path?: string): void

Usuwa jeden wpis albo, wywołana bez argumentów, całą pamięć podręczną kompilacji.

Klasy błędów

KlasaRzucana, gdyDodatkowe pola
VersoSyntaxErrorSzablonu nie da się sparsowaćfile, line, column, frame
VersoLookupErrorW trybie ścisłym brakuje właściwościpath, file, line
VersoRenderErrorFiltr lub odroczony blok rzuca wyjątekcause, node, file, line

Wszystkie trzy rozszerzają Error i ustawiają name na nazwę klasy. Pole frame zawiera dwuliniowy fragment ze znacznikiem pod błędnym tokenem:

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

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

TypeScript

Deklaracje są dołączone. TemplateFn jest generyczny względem kształtu danych, więc możesz powiązać szablon z interfejsem:

import type { TemplateFn } from 'verso';

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

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

Kompilator nie sprawdza treści szablonów względem typu — wymagałoby to parsera świadomego typów, a dwukrotnie zdecydowaliśmy, że go nie zbudujemy.