71 lines
2.0 KiB
JavaScript
71 lines
2.0 KiB
JavaScript
const sortTags = (a, b) => a._w === b._w ? a._p - b._p : a._w - b._w;
|
|
const TAG_WEIGHTS = {
|
|
base: -10,
|
|
title: 10
|
|
};
|
|
const TAG_ALIASES = {
|
|
critical: -8,
|
|
high: -1,
|
|
low: 2
|
|
};
|
|
const WEIGHT_MAP = {
|
|
meta: {
|
|
"content-security-policy": -30,
|
|
"charset": -20,
|
|
"viewport": -15
|
|
},
|
|
link: {
|
|
"preconnect": 20,
|
|
"stylesheet": 60,
|
|
"preload": 70,
|
|
"modulepreload": 70,
|
|
"prefetch": 90,
|
|
"dns-prefetch": 90,
|
|
"prerender": 90
|
|
},
|
|
script: {
|
|
async: 30,
|
|
defer: 80,
|
|
sync: 50
|
|
},
|
|
style: {
|
|
imported: 40,
|
|
sync: 60
|
|
}
|
|
};
|
|
const ImportStyleRe = /@import/;
|
|
const isTruthy = (val) => val === "" || val === true;
|
|
function tagWeight(head, tag) {
|
|
if (typeof tag.tagPriority === "number")
|
|
return tag.tagPriority;
|
|
let weight = 100;
|
|
const offset = TAG_ALIASES[tag.tagPriority] || 0;
|
|
const weightMap = head.resolvedOptions.disableCapoSorting ? {
|
|
link: {},
|
|
script: {},
|
|
style: {}
|
|
} : WEIGHT_MAP;
|
|
if (tag.tag in TAG_WEIGHTS) {
|
|
weight = TAG_WEIGHTS[tag.tag];
|
|
} else if (tag.tag === "meta") {
|
|
const metaType = tag.props["http-equiv"] === "content-security-policy" ? "content-security-policy" : tag.props.charset ? "charset" : tag.props.name === "viewport" ? "viewport" : null;
|
|
if (metaType)
|
|
weight = WEIGHT_MAP.meta[metaType];
|
|
} else if (tag.tag === "link" && tag.props.rel) {
|
|
weight = weightMap.link[tag.props.rel];
|
|
} else if (tag.tag === "script") {
|
|
if (isTruthy(tag.props.async)) {
|
|
weight = weightMap.script.async;
|
|
} else if (tag.props.src && !isTruthy(tag.props.defer) && !isTruthy(tag.props.async) && tag.props.type !== "module" && !tag.props.type?.endsWith("json")) {
|
|
weight = weightMap.script.sync;
|
|
} else if (isTruthy(tag.props.defer) && tag.props.src && !isTruthy(tag.props.async)) {
|
|
weight = weightMap.script.defer;
|
|
}
|
|
} else if (tag.tag === "style") {
|
|
weight = tag.innerHTML && ImportStyleRe.test(tag.innerHTML) ? weightMap.style.imported : weightMap.style.sync;
|
|
}
|
|
return (weight || 100) + offset;
|
|
}
|
|
|
|
export { sortTags as s, tagWeight as t };
|