UNPKG

@pandabox/postcss-plugins

Version:

- `removeUnusedCssVars` - `removeUnusedKeyframes`

78 lines (63 loc) 2.1 kB
import postcss, { type TransformCallback } from 'postcss' interface UseRecord { uses: number dependencies: Set<string> declarations: Set<postcss.Declaration> } const varRegex = /var\(\s*(?<name>--[^ ,);]+)/g /** * Adapted from https://github.com/tomasklaen/postcss-prune-var/blob/57ad5041806b73479d0c558e0b1a918803cb7cbc/index.js */ export const removeUnusedCssVars: TransformCallback = (root) => { const records = new Map<string, UseRecord>() const getRecord = (variable: string): UseRecord => { let record = records.get(variable) if (!record) { record = { uses: 0, dependencies: new Set(), declarations: new Set() } records.set(variable, record) } return record } const registerUse = (variable: string, ignoreList = new Set<string>()) => { 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: string, dependency: string) => { const record = getRecord(variable) record.dependencies.add(dependency) } // Detect variable uses root.walkDecls((decl) => { const parent = decl.parent if (!parent) return if (parent.type === 'rule' && (parent as postcss.Rule).selector === ':root') { return } const isVar = decl.prop.startsWith('--') // Initiate record 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) } } }) // Remove unused variables 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() } } } }