Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
function purge (css) {
// Files to search for used selectors. Used selectors will not be purged.
const content = [
'./src/views/*.js',
'./src/server/*.ejs'
]
// Whitelist of selectors to never purge
const whitelistPatternsChildren = [
// Theme colors
...Object.values(theme).map(color => new RegExp(`.*?${color}.*?`))
]
const purgeCss = new PurgeCss({
css,
content,
whitelistPatternsChildren,
keyframes: true,
rejected: argv.debug
})
const files = purgeCss.purge()
// Print removed CSS selectors
if (argv.debug) {
files.forEach(file => {
console.log(`Removed from ${file.file}:`)
file.rejected.forEach(rejectedDecl => console.log(` ${rejectedDecl}`))
})
}
const defaults = {
content,
keyframes: true,
rejected: debug,
whitelistPatternsChildren: [/svelte-/],
};
const opts = Object.assign(defaults, options, {
css: [
{
extension: 'css',
raw: code,
},
],
});
const result = new Purgecss(opts).purge()[0];
if (result.rejected && result.rejected.length) {
// eslint-disable-next-line no-console
console.log('[purgecss] Rejected selectors', id, result.rejected);
}
// eslint-disable-next-line consistent-return
return {
code: result.css,
};
} catch (err) {
this.error(err);
}
},
};
if (options.purgeOnly.some(file => normalizedPath.includes(file))) {
console.log(
'\ngatsby-plugin-purgecss: Only processing ',
this.resourcePath
);
} else {
stats.addRemovedSize(source);
return source;
}
}
let css;
try {
// @ts-ignore
css = new PurgeCss({
css: [{ raw: source }],
...options
}).purge();
} catch (error) {
console.log(
'\ngatsby-plugin-purgecss: Could not parse file, skipping. Your build will not break.\n',
this.resourcePath
);
if (options.debug) {
Debug.writeAppendError(error);
} else {
console.log('Use debug option to investigate further.');
}
return source;
transform(code, id) {
if (!filter(id)) return null
const purgecss = new Purgecss({
content: options.content,
css: [{
raw: code
}]
})
let css = purgecss.purge()[0].css
styles.push(css)
css = JSON.stringify(css)
if (options.insert) {
// do thing
} else if (!options.output) {
code = css
} else {
code = `"";`
}
// Compile through Purgecss and attach to output.
// This loses sourcemaps should there be any!
var options = _extends({}, _this.options, {
content: filesToSearch,
css: [{
raw: asset.source()
}]
});
if (typeof options.whitelist === 'function') {
options.whitelist = options.whitelist();
}
if (typeof options.whitelistPatterns === 'function') {
options.whitelistPatterns = options.whitelistPatterns();
}
var purgecss = new Purgecss(options);
compilation.assets[name] = new ConcatSource(purgecss.purge()[0].css);
});
});
const getStartupCSS = async ({ htmlPaths, cssPaths, purgeOptions }) => {
const content = htmlPaths.map((htmlPath) => {
if (!fs.existsSync(htmlPath)) {
die(`Could not find fixture "${htmlPath}". Have you run the fixtures?`);
}
const rawHtml = fs.readFileSync(htmlPath);
const html = cleanHtml(rawHtml);
return { raw: html, extension: 'html' };
});
const purgeCSSResult = await new PurgeCSS().purge({
content,
css: cssPaths,
...mergePurgeCSSOptions(
{
fontFace: true,
variables: true,
keyframes: true,
blocklist: [/:hover/, /:focus/, /-webkit-/, /-moz-focusring-/, /-ms-expand/],
safelist: {
standard: ['brand-header-logo'],
},
// By default, PurgeCSS ignores special characters, but our utilities use "!"
defaultExtractor: (x) => x.match(/[\w-!]+/g),
extractors: [
{
extractor: purgeHtml,
{
raw: asset.source()
}
]
}
if (typeof options.whitelist === 'function') {
options.whitelist = options.whitelist()
}
if (typeof options.whitelistPatterns === 'function') {
options.whitelistPatterns = options.whitelistPatterns()
}
if (typeof options.whitelistPatternsChildren === 'function') {
options.whitelistPatternsChildren = options.whitelistPatternsChildren()
}
const purgecss = new Purgecss(options)
const purged = purgecss.purge()[0]
if (purged.rejected) {
purgedStats[name] = purged.rejected
}
compilation.assets[name] = new ConcatSource(purged.css)
})
})
transform(code, id) {
if (!filter(id)) return null;
const purgecss = new Purgecss({
content: options.content,
css: [{
raw: code
}]
});
let css = purgecss.purge()[0].css;
styles.push(css);
css = JSON.stringify(css);
if (options.insert) ; else if (!options.output) {
code = css;
} else {
code = `"";`;
}
return {
}]
});
if (typeof options.whitelist === 'function') {
options.whitelist = options.whitelist();
}
if (typeof options.whitelistPatterns === 'function') {
options.whitelistPatterns = options.whitelistPatterns();
}
if (typeof options.whitelistPatternsChildren === 'function') {
options.whitelistPatternsChildren = options.whitelistPatternsChildren();
}
var purgecss = new Purgecss(options);
var purged = purgecss.purge()[0];
if (purged.rejected) {
purgedStats[name] = purged.rejected;
}
compilation.assets[name] = new ConcatSource(purged.css);
});
});
return async function(s, t) {
const r = new purgecss.PurgeCSS(),
o = { ...purgecss.defaultOptions, ...e };
r.options = o;
const { content: c, extractors: n } = o,
u = c.filter(e => "string" == typeof e),
p = c.filter(e => "object" == typeof e),
i = await r.extractSelectorsFromFiles(u, n),
l = r.extractSelectorsFromString(p, n),
g = purgecss.mergeExtractorSelectors(i, l);
r.walkThroughCSS(s, g),
r.options.fontFace && r.removeUnusedFontFaces(),
r.options.keyframes && r.removeUnusedKeyframes(),
r.options.rejected &&
r.selectorsRemoved.size > 0 &&
(t.messages.push({
type: "purgecss",
plugin: "postcss-purgecss",