@pandabox/postcss-plugins
Version:
- `removeUnusedCssVars` - `removeUnusedKeyframes`
86 lines (84 loc) • 2.56 kB
JavaScript
// src/remove-unused-css-vars.ts
import "postcss";
var varRegex = /var\(\s*(?<name>--[^ ,);]+)/g;
var removeUnusedCssVars = (root) => {
const records = /* @__PURE__ */ new Map();
const getRecord = (variable) => {
let record = records.get(variable);
if (!record) {
record = { uses: 0, dependencies: /* @__PURE__ */ new Set(), declarations: /* @__PURE__ */ new Set() };
records.set(variable, record);
}
return record;
};
const registerUse = (variable, ignoreList = /* @__PURE__ */ new Set()) => {
const record = getRecord(variable);
record.uses++;
ignoreList.add(variable);
for (const dependency of record.dependencies) {
if (!ignoreList.has(dependency))
registerUse(dependency, ignoreList);
}
};
const registerDependency = (variable, dependency) => {
const record = getRecord(variable);
record.dependencies.add(dependency);
};
root.walkDecls((decl) => {
const parent = decl.parent;
if (!parent)
return;
if (parent.type === "rule" && parent.selector === ":root") {
return;
}
const isVar = decl.prop.startsWith("--");
if (isVar)
getRecord(decl.prop).declarations.add(decl);
if (!decl.value.includes("var("))
return;
for (const match of decl.value.matchAll(varRegex)) {
const variable = match.groups?.name.trim();
if (!variable)
continue;
if (isVar) {
registerDependency(decl.prop, variable);
} else {
registerUse(variable);
}
}
});
for (const { uses, declarations } of records.values()) {
if (uses === 0) {
for (const decl of declarations) {
if (decl.parent?.nodes?.length === 1)
decl.parent?.remove();
else
decl.remove();
}
}
}
};
// src/remove-unused-keyframes.ts
var removeUnusedKeyframes = (root) => {
const keyframes = /* @__PURE__ */ new Map();
root.walk((node) => {
if (node.type === "atrule" && node.name === "keyframes") {
keyframes.set(node.params, false);
} else if (node.type === "decl") {
const decl = node;
const animationName = decl.prop === "animation" ? decl.value.split(" ")[0] : decl.value;
if ((decl.prop === "animation" || decl.prop === "animation-name") && keyframes.has(animationName)) {
keyframes.set(animationName, true);
}
}
});
root.walkAtRules("keyframes", (rule) => {
if (keyframes.get(rule.params) === false) {
rule.remove();
}
});
};
export {
removeUnusedCssVars,
removeUnusedKeyframes
};