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