`ultrahtml` library in Nitro codebase.
In this article, we review how Nitro uses ultrahtml package. We will look at:
-
What is
ultrahtml
library? -
How is
ultrahtml
used in Nitro codebase?
I study patterns used in an open source project found on Github Trending. For this week, I reviewed some parts of Nitro codebase and wrote this article.
Press enter or click to view image in full size
What is ultrahtml
library?
A 1.75kB library for enhancing html
. ultrahtml
has zero dependencies and is compatible with any JavaScript runtime.
Features
-
Tiny, fault-tolerant and friendly HTML-like parser. Works with HTML, Astro, Vue, Svelte, and any other HTML-like syntax.
-
Built-in AST
walk
utility -
Built-in
transform
utility for easy output manipulation -
Automatic but configurable sanitization, see Sanitization
-
Handy
html
template utility -
querySelector
andquerySelectorAll
support usingultrahtml/selector
Learn more about ultrahtml.
How is ultrahtml
used in Nitro codebase?
I found the below import in nitro/src/prerender/utils.ts.
import { parse as parseHTML, walk } from "ultrahtml";
And these functions are used in extractLinks function defined at L25.
export async function extractLinks(
html: string,
from: string,
res: Response,
crawlLinks: boolean
) {
const links: string[] = [];
const _links: string[] = [];
// Extract from any <TAG href=""> to crawl
if (crawlLinks) {
await walk(parseHTML(html), (node) => {
if (!node.attributes?.href) {
return;
}
const link = escapeHtml(node.attributes.href);
if (
!decodeURIComponent(link).startsWith("#") &&
allowedExtensions.has(getExtension(link))
) {
_links.push(link);
}
});
}
but what does walk function do? I picked the following information from the ultrahtml README.
walk
The walk
function provides full control over the AST. It can be used to scan for text, elements, components, or any other validation you might want to do.
Note:
walk
isasync
and must beawait
ed. UsewalkSync
if it is guaranteed there are noasync
components in the tree.
import { parse, walk, ELEMENT_NODE } from "ultrahtml";
const ast = parse(`<h1>Hello world!</h1>`);
await walk(ast, async (node) => {
if (node.type === ELEMENT_NODE && node.name === "script") {
throw new Error("Found a script!");
}
});
About me:
Hey, my name is Ramu Narasinga. I study codebase architecture in large open-source projects.
Email: ramu.narasinga@gmail.com
Study the patterns used in large OSS projects at Think Throo.
References:
-
https://github.com/nitrojs/nitro/blob/main/src/prerender/utils.ts#L4
-
https://github.com/nitrojs/nitro/blob/main/src/prerender/utils.ts#L36