Skip to content

Instantly share code, notes, and snippets.

@antstanley
Last active September 12, 2022 21:43
Show Gist options
  • Save antstanley/82fa3a8d1910858a3401ee64dc9728f8 to your computer and use it in GitHub Desktop.
Save antstanley/82fa3a8d1910858a3401ee64dc9728f8 to your computer and use it in GitHub Desktop.
Using PurgeCSS and CleanCSS with 11ty to remove unused CSS selectors
const Purgecss = require('purgecss')
const { JSDOM } = require('jsdom')
const CleanCSS = require("clean-css");
//array of css files to combine
const cssFiles = ['./src/css/custom.css','./src/css/markdown.css', './src/css/tachyons.css']
// cleanCSSOptions for minification and inlining css, will fix duplicate media queries
const cleanCSSOptions = {
level: {
2: {
all: true,
removeDuplicateRules: true
}
}
}
//function to insert css into the DOM
const insertCss = (html, css) => {
const dom = new JSDOM(html)
const { document } = dom.window
let head = document.getElementsByTagName('head')[0];
let style = document.createElement("style");
style.type = 'text/css';
style.innerHTML = css;
head.appendChild(style);
return dom.serialize()
}
module.exports = function (eleventyConfig) {
eleventyConfig.addTransform("purgeCSS", function(content, outputPath){
if( outputPath.endsWith(".html") ) {
console.log(outputPath)
const purgecss = new Purgecss({
content: [outputPath],
css: cssFiles
})
const purgecssResult = purgecss.purge()
let cssMerge = ''
if(purgecssResult.length>0){
for (let i = 0; i < purgecssResult.length; i++){
cssMerge= cssMerge.concat(purgecssResult[i].css)
}
const cssMin = new CleanCSS(cleanCSSOptions).minify(cssMerge).styles
return insertCss(content, cssMin)
}
}
return content
})
}
@stuartjnelson
Copy link

stuartjnelson commented Dec 29, 2020

Thanks for sharing this. I got errors with this snippet. I changing the import and;

const purgecssResult = await new PurgeCSS().purge({
  content: [outputPath],
  css: cssFiles
 });
const { PurgeCSS } = require('purgecss')
const { JSDOM } = require('jsdom')
const CleanCSS = require("clean-css");

//function to insert css into the DOM
const insertCss = (html, css) => {
	const dom = new JSDOM(html)
	const { document } = dom.window

	let head = document.getElementsByTagName('head')[0];
	let style = document.createElement("style");

	style.type = 'text/css';
	style.innerHTML = css;
    
	head.appendChild(style);

	return dom.serialize()
}

module.exports = (eleventyConfig) => {
  eleventyConfig.addTransform("purgeCSS", async function(content, outputPath) {
    if (outputPath.endsWith(".html")) {
      //array of css files to combine
      const cssFiles = ['./_site/assets/style.css']
  
      // cleanCSSOptions for minification and inlining css, will fix duplicate media queries
      const cleanCSSOptions = {
        level: {
          2: {
            all: true,
            removeDuplicateRules: true
          }
        }
      }
  
      const purgecssResult = await new PurgeCSS().purge({
        content: [outputPath],
        css: cssFiles
      });
  
      let cssMerge = '';
  
      if (purgecssResult.length > 0) {
        for (let i = 0; i < purgecssResult.length; i++) {
          cssMerge = cssMerge.concat(purgecssResult[i].css)
        }
        const cssMin = new CleanCSS(cleanCSSOptions).minify(cssMerge).styles
  
        return insertCss(content, cssMin)
      }
    }
    return content
  })
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment