purgecss-custom-extractor v0.2.4
A tool to easily create custom extractors for purgecss.
Install
npm i purgecss-custom-extractorUsage
Accepts regex as a RegExp or a string with it ('\w+', '/\w+/g')
First argument can be a regex or an array of regex and match processor or a list with a mix of both.
const purgeCss = new Purgecss({
content: ['**/*.html'],
css: ['**/*.css'],
extractors: [{
// 'g' flag will be enforced.
extractor: Extractor.custom(/[a-zA-Z0-9\-_]+/),
extensions: ['html']
}]
})By default purgecss treats every word in text as potential selector. But what if you're using some selectors that contain a non standard characters, like in TailwindCSS framework (w-1/2, hover:bg-blue). Or your code contains a lot of static text, then you can get lots of selectors you don't really use. You can create a simple regular expression to only keep selectors that are mentioned in class attribute of html tags. If you pass an array of [regex, matchProcessor] then each match will go through that passed function.
// getting all the tags with class attribute
// taking first group in each match that contains
// class list and splitting it by ' '
Extractor.custom([ /<[\w]+.*?class="(.*?)".*?>/mg, m => m[1].split(' ') ])If you want you can get rid of html comments <!-- --> to ignore class names in commented code. To do this you can define contentProcessor and remove html comments before looking for matches.
// Extractor.regex.comment() == /<!--([\s\S]*?)-->/mg
Extractor.custom({
regex: [ /<[\w]+.*?class="(.*?)".*?>/mg, m => m[1].split(' ') ],
contentProcessor: c => c.replace(Extractor.regex.comment(), '')
})You can also trim text to a content of a specific html tag. This also can be useful when working with VueJS single file components, you can isolate <template> tag and look for matches only there.
Extractor.custom({
regex: [ /<[\w]+.*?class="(.*?)".*?>/mg, m => m[1].split(' ') ],
contentProcessor: content => {
// generate regexp for lazy template tag
let regex = Extractor.regex.lazyTag('template')
let match = regex.exec(content)
// if match found use second group for tags content
// for reference see api -> regex
let res = match ? match[2] : content
return res
}
})API
custom(regex | {regex, matchProcessor, contentProcessor})
Function to create custom extractor
First argument can be either of these:
regex: a regex, array of regex and match processor or a mixed list of bothcustom(regex); custom([regex, eachMatch]); custom([ [regex, eachMatch], [regex], regex ]); custom({regex, matchProcessor, contentProcessor});opts: object with options:
matchAll(re, text, matchProcessor)
Function to get all the matches from given string
re: RegExp or string with it ('\w+','/\w+/g')text: text to match inmatchProcessor: optional will receive result of each match and will return processed value, can return string or array of strings (m => m[1])returns: array of all the matched strings
regex
Object containing methods to create predefined regular expressions.
simple(): returns regex for simple css selector (/[a-zA-Z0-9\-_]+/g)extended(): returns regex for css selector with:and\characters (/[a-zA-Z0-9\-_:\/]+/g) such css selectors are being used in some frameworks, like TailwindCSSlazyTag(tagName): returns regex to match multiline html tag with it's content (/<div(.*?)>([\s\S]*?)<\/divs*>/mg) group 1 - attributes, group 2 - contentgreedyTag(tagName): same as above but greedy for content group (/<div(.*?)>([\s\S]*)<\/divs*>/mg)comment(): returns regex to match html comments (/<!--([\s\S]*?)-->/mg)
whitelist
Object containing whitelist presets
htmltags: array of html tag names
simple()
Predefined Extractor with regex.simple().
() => custom({regex: regex.simple()})extended()
Predefined Extractor with regex.extended().
() => custom({regex: regex.extended()})