Last active
December 15, 2022 07:05
-
-
Save dqh-au/4653d8a1f5526a0d533a66e1e66720b7 to your computer and use it in GitHub Desktop.
Shorten CSS variable names using CSSTree
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function shortenCssVariableNames(cssAst, digitSymbols, namesToPreserve = []) | |
{ | |
// | |
// First figure out how often each variable name is used, | |
// as we want the shortest replacement names to go to those | |
// used the most. | |
// | |
const nameUsage = {}; | |
csstree.walk( | |
cssAst, | |
node => | |
{ | |
let name; | |
if (node.type === 'Declaration' && node.property.startsWith('--')) | |
name = node.property; | |
else if (node.type === 'Identifier' && node.name.startsWith('--')) | |
name = node.name; | |
else | |
return; | |
if (nameUsage[name]) | |
nameUsage[name]++; | |
else | |
nameUsage[name] = 1; | |
}); | |
// Sort the variables from most to least used. | |
const sortedNameUsage = Object.entries(nameUsage).sort(([,a], [,b]) => b - a); | |
// | |
// Now assign replacement names | |
// | |
const preserveNames = new Set(namesToPreserve); | |
const renamedVariables = new Map(); | |
const base = digitSymbols.length; | |
let nextNameIndex = 0; | |
function newVariableName() | |
{ | |
let i = nextNameIndex++; | |
let name = ''; | |
// Convert nameIndex to new base based on the number of digit symbols | |
do | |
{ | |
const digitIndex = i % base; | |
name = digitSymbols.charAt(digitIndex) + name; | |
i = (i - digitIndex) / base; | |
} | |
while (i); | |
return '--' + name; | |
} | |
for (const [name, count] of sortedNameUsage) | |
{ | |
if (preserveNames.has(name)) | |
renamedVariables.set(name, name) | |
else | |
renamedVariables.set(name, newVariableName()); | |
} | |
// | |
// Finally, apply our name replacements | |
// | |
csstree.walk( | |
cssAst, | |
node => | |
{ | |
if (node.type === 'Declaration' && node.property.startsWith('--')) | |
node.property = renamedVariables.get(node.property); | |
else if (node.type === 'Identifier' && node.name.startsWith('--')) | |
node.name = renamedVariables.get(node.name); | |
}); | |
} | |
// 1. Use CSSTree to create an AST from css code | |
let ast = csstree.parse(css); | |
// 2. Replace css variable names with short ones generated using supplied character set | |
shortenCssVariableNames( | |
ast, | |
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", | |
[ /* names to keep go here */ ]); | |
// 3. Turn the AST back into CSS code. | |
css = csstree.generate(ast); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment