Last active
April 18, 2016 16:22
-
-
Save byrichardpowell/17227066383d916854178ccedf6ddea7 to your computer and use it in GitHub Desktop.
Super simple node script to find CSS that is no longer in use. The results should be considered as safe as a global find and replace (not very), so use your judgement
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
var walk = require('walk'); | |
var fs = require('fs'); | |
var classesOrIds = []; | |
var viewsAndTemplates = [] | |
var walkers = []; | |
var maybeUnusedClassesOrIds = []; | |
var compleWalkersCount = 0; | |
var classesToFileMap = {} | |
// Calback Function every time a walker ends | |
var onWalkerEnd = function(walkerId) { | |
compleWalkersCount++ | |
// All walkers are complete | |
// We can only perform this logic once we have all the data | |
if (compleWalkersCount === walkers.length) { | |
// Loop through all the classes or IDs | |
for (i = 0; i < classesOrIds.length; i++) { | |
// The class or ID we are looking for | |
classOrId = classesOrIds[i] | |
// Loop through all the views and Templates | |
for (ii = 0; ii < viewsAndTemplates.length; ii++) { | |
// We found this class or ID in a view or template | |
if (viewsAndTemplates[ii].indexOf(classOrId.substring(1)) > -1) { | |
break; | |
} | |
// We didnt find this class or id inside any view or template | |
if (ii === viewsAndTemplates.length -1) { | |
maybeUnusedClassesOrIds.push(classOrId) | |
} | |
} | |
} | |
console.log("Found " + classesOrIds.length + " CSS classes or ids"); | |
console.log(maybeUnusedClassesOrIds.length + " of those might not be in use anymore:"); | |
console.log(" "); | |
// Log each class or ID that we couldnt find | |
maybeUnusedClassesOrIds.forEach(function(classOrId) { | |
logString = classOrId | |
// Right Pad the string so we a nice column of locations | |
for (i = 0; i < 40 - classOrId.length; i++) { | |
logString += " " | |
} | |
console.log(logString + classesToFileMap[classOrId]); | |
}) | |
} | |
}; | |
// Gets all the CSS Classes or Ids | |
walkers.push(walk.walk('./app/assets/css', { followLinks: false }).on('file', function(root, stat, next) { | |
// Opens each file | |
// Note this will open other files as well | |
fs.readFile(root + '/' + stat.name, 'utf8', function(error, data) { | |
// Assume the CSS is unminified | |
// If so we assume that each selector starts on a new line | |
data.split('\n').forEach(function(line) { | |
// Find Class selectors | |
// Assume that lines starting with a . are a class selectors | |
// Note this won't catch instances of element.class | |
if (line[0] === '.') { | |
name = line.split('.')[1].split(' ')[0].split(':')[0].split('\t')[0].split(',')[0].split('[')[0]; | |
if (classesOrIds.indexOf("." + name) === -1) { | |
classesOrIds.push("." + name); | |
classesToFileMap["." + name] = root + '/' + stat.name; | |
} | |
} | |
// Find ID selectors | |
// Assume that lines starting with a # are ID selectors | |
// Note this won't catch instances of element#id | |
if (line[0] === '#') { | |
name = line.split('#')[1].split(' ')[0].split(':')[0].split('\t')[0].split(',')[0].split('[')[0].split('.')[0]; | |
if (classesOrIds.indexOf("#" + name) === -1) { | |
classesOrIds.push("#" + name); | |
classesToFileMap["#" + name] = root + '/' + stat.name; | |
} | |
} | |
}) | |
next(); | |
}); | |
}).on('end', onWalkerEnd)); | |
// Gets all the mustache templates | |
walkers.push(walk.walk('./app/templates', { followLinks: false }).on('file', function(root, stat, next) { | |
// Read & save the content of the mustache template | |
// We'll check this for classes or ids later | |
fs.readFile(root + '/' + stat.name, 'utf8', function(error, data) { | |
viewsAndTemplates.push(data); | |
next(); | |
}); | |
}).on('end', onWalkerEnd)); | |
// Gets all the views/components | |
walkers.push(walk.walk('./app/coffeescript/views', { followLinks: false }).on('file', function(root, stat, next) { | |
// Read & save the content of the view | |
// We'll check this for classes or ids later | |
fs.readFile(root + '/' + stat.name, 'utf8', function(error, data) { | |
viewsAndTemplates.push(data) | |
next(); | |
}); | |
}).on('end', onWalkerEnd)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment