v0.106.0: Removal of cheerio

The api.cheerio library has been removed from the backend scripting API.

Scripts that attempt to use api.cheerio will now throw an error with migration instructions.

Reasoning#

cheerio was deprecated in v0.103.0 in favor of api.htmlParser (node-html-parser), which Trilium already uses for all of its own HTML parsing. The scripting API was the only place that still needed cheerio.

Shipping both parsers was costly, because cheerio was loaded at startup on every platform. It added roughly 1.35 MB of bundled code to the server and desktop builds, and roughly 370 kB to the in-browser build, where it was loaded into the database worker before the application could start.

Migration#

Replace api.cheerio calls with api.htmlParser. Note that api.htmlParser returns plain elements rather than a wrapped collection, so there is no $ object and no chaining.

Reading values#

Before (cheerio):

const $ = api.cheerio.load(html);
const title = $('h1').text();
const links = $('a').map((i, el) => $(el).attr('href')).get();

After (htmlParser):

const root = api.htmlParser.parse(html);
const title = root.querySelector('h1')?.textContent;
const links = root.querySelectorAll('a').map(a => a.getAttribute('href'));

Modifying the document#

Before (cheerio):

const $ = api.cheerio.load(html);
$('a').each((i, el) => {
    $(el).attr('href', '#root/' + noteId);
    $(el).addClass('reference-link');
});
note.setContent($('body').html());

After (htmlParser):

const root = api.htmlParser.parse(html);
for (const el of root.querySelectorAll('a')) {
    el.setAttribute('href', '#root/' + noteId);
    el.classList.add('reference-link');
}
note.setContent(root.toString());

Equivalent operations#

cheeriohtmlParser
api.cheerio.load(html)api.htmlParser.parse(html)
$('sel')root.querySelectorAll('sel')
$('sel').first()root.querySelector('sel')
$el.text()el.textContent
$el.html()el.innerHTML
$el.attr('name')el.getAttribute('name')
$el.attr('name', value)el.setAttribute('name', value)
$el.addClass('name')el.classList.add('name')
$('body').html()root.toString()