UNPKG

vite-plugin-capo

Version:

Reorders HTML <head> elements in Vite projects at build time using capo.js guidelines to improve page load performance.

121 lines (120 loc) 2.72 kB
import { parse as N, serialize as P } from "parse5"; const h = (t) => t.nodeName !== "#text" && "tagName" in t, n = { Async: "async", Charset: "charset", Defer: "defer", HttpEquiv: "http-equiv", Name: "name", Rel: "rel", Type: "type" }, c = { DnsPrefetch: "dns-prefetch", ModulePreload: "modulepreload", Preconnect: "preconnect", Prefetch: "prefetch", Preload: "preload", Prerender: "prerender", Stylesheet: "stylesheet" }, l = { Base: "base", Link: "link", Meta: "meta", Script: "script", Style: "style", Title: "title" }, S = [ "accept-ch", "content-security-policy", "content-type", "default-style", "delegate-ch", "origin-trial", "x-dns-prefetch-control" ], a = (t, s) => t.attrs.find((p) => p.name === s)?.value, g = (t) => { const s = [], p = [], o = [], r = [], f = [], m = [], d = [], y = [], b = [], k = [], u = []; for (const e of t) { if (!h(e)) { u.push(e); continue; } switch (e.tagName) { case l.Base: { s.push(e); break; } case l.Link: { switch (a(e, n.Rel)) { case c.DnsPrefetch: case c.Prefetch: case c.Prerender: k.push(e); break; case c.ModulePreload: case c.Preload: y.push(e); break; case c.Preconnect: o.push(e); break; case c.Stylesheet: d.push(e); break; default: u.push(e); break; } break; } case l.Meta: { const i = a(e, n.HttpEquiv); i && S.includes(i) || a(e, n.Charset) || a(e, n.Name) === "viewport" ? s.push(e) : u.push(e); break; } case l.Script: { a(e, n.Async) ? r.push(e) : a(e, n.Defer) || a(e, n.Type) === "module" ? b.push(e) : m.push(e); break; } case l.Style: { e.childNodes.some((i) => i.nodeName === "#text" && "value" in i && i.value.includes("@import")) ? f.push(e) : d.push(e); break; } case l.Title: { p.push(e); break; } default: { u.push(e); break; } } } return [ ...s, ...p, ...o, ...r, ...f, ...m, ...d, ...y, ...b, ...k, ...u ]; }, v = (t) => { const s = N(t), o = s.childNodes.find((r) => h(r) && r.tagName === "html")?.childNodes.find((r) => h(r) && r.tagName === "head"); return o ? (o.childNodes = g(o.childNodes), P(s)) : t; }; function T() { return { name: "vite-plugin-capo", enforce: "post", apply: "build", transformIndexHtml(t) { return v(t); } }; } export { T as capo };