From 81aaadbabffe4e5e0663b3b51f10dbd371d2593d Mon Sep 17 00:00:00 2001 From: Jason Miller Date: Tue, 1 May 2018 09:52:58 -0400 Subject: [PATCH] Remove all prerendering & critical CSS stuff --- config/critters-webpack-plugin.js | 409 ----------------- config/prerender-loader.js | 222 --------- config/prerender.js | 20 - package-lock.json | 727 +----------------------------- package.json | 11 +- webpack.config.js | 16 +- 6 files changed, 25 insertions(+), 1380 deletions(-) delete mode 100644 config/critters-webpack-plugin.js delete mode 100644 config/prerender-loader.js delete mode 100644 config/prerender.js diff --git a/config/critters-webpack-plugin.js b/config/critters-webpack-plugin.js deleted file mode 100644 index d0a9894c..00000000 --- a/config/critters-webpack-plugin.js +++ /dev/null @@ -1,409 +0,0 @@ -const path = require('path'); -const parse5 = require('parse5'); -const nwmatcher = require('nwmatcher'); -const css = require('css'); -const prettyBytes = require('pretty-bytes'); - -const treeAdapter = parse5.treeAdapters.htmlparser2; - -const PLUGIN_NAME = 'critters-webpack-plugin'; - -const PARSE5_OPTS = { - treeAdapter -}; - -/** Critters: Webpack Plugin Edition! - * @class - * @param {Object} options - * @param {Boolean} [options.external=true] Fetch and inline critical styles from external stylesheets - * @param {Boolean} [options.async=false] Convert critical-inlined external stylesheets to load asynchronously (via link rel="preload" - see https://filamentgroup.com/lab/async-css.html) - * @param {Boolean} [options.preload=false] (requires `async` option) Append a new into instead of swapping the preload's rel attribute - * @param {Boolean} [options.fonts] If `true`, keeps critical `@font-face` rules and preloads them. If `false`, removes the rules and does not preload the fonts - * @param {Boolean} [options.preloadFonts=false] Preloads critical fonts (even those removed by `{fonts:false}`) - * @param {Boolean} [options.removeFonts=false] Remove all fonts (even critical ones) - * @param {Boolean} [options.compress=true] Compress resulting critical CSS - */ -module.exports = class CrittersWebpackPlugin { - constructor (options) { - this.options = options || {}; - this.urlFilter = this.options.filter; - if (this.urlFilter instanceof RegExp) { - this.urlFilter = this.urlFilter.test.bind(this.urlFilter); - } - } - - /** Invoked by Webpack during plugin initialization */ - apply (compiler) { - // hook into the compiler to get a Compilation instance... - compiler.hooks.compilation.tap(PLUGIN_NAME, compilation => { - // ... which is how we get an "after" hook into html-webpack-plugin's HTML generation. - compilation.hooks.htmlWebpackPluginAfterHtmlProcessing.tapAsync(PLUGIN_NAME, (htmlPluginData, callback) => { - this.process(compiler, compilation, htmlPluginData) - .then(result => { callback(null, result); }) - .catch(callback); - }); - }); - } - - readFile (filename, encoding) { - return new Promise((resolve, reject) => { - this.fs.readFile(filename, encoding, (err, data) => { - if (err) reject(err); - else resolve(data); - }); - }); - } - - async process (compiler, compilation, htmlPluginData) { - const outputPath = compiler.options.output.path; - - // Parse the generated HTML in a DOM we can mutate - const document = parse5.parse(htmlPluginData.html, PARSE5_OPTS); - makeDomInteractive(document); - - // `external:false` skips processing of external sheets - if (this.options.external !== false) { - const externalSheets = document.querySelectorAll('link[rel="stylesheet"]'); - await Promise.all(externalSheets.map( - link => this.embedLinkedStylesheet(link, compilation, outputPath) - )); - } - - // go through all the style tags in the document and reduce them to only critical CSS - const styles = document.querySelectorAll('style'); - await Promise.all(styles.map( - style => this.processStyle(style, document) - )); - - // serialize the document back to HTML and we're done - const html = parse5.serialize(document, PARSE5_OPTS); - return { html }; - } - - /** Inline the target stylesheet referred to by a (assuming it passes `options.filter`) */ - async embedLinkedStylesheet (link, compilation, outputPath) { - const href = link.getAttribute('href'); - const document = link.ownerDocument; - - // skip filtered resources, or network resources if no filter is provided - if (this.urlFilter ? this.urlFilter(href) : href.match(/^(https?:)?\/\//)) return Promise.resolve(); - - // path on disk - const filename = path.resolve(outputPath, href.replace(/^\//, '')); - - // try to find a matching asset by filename in webpack's output (not yet written to disk) - const asset = compilation.assets[path.relative(outputPath, filename).replace(/^\.\//, '')]; - - // CSS loader is only injected for the first sheet, then this becomes an empty string - let cssLoaderPreamble = `function $loadcss(u,l){(l=document.createElement('link')).rel='stylesheet';l.href=u;document.head.appendChild(l)}`; - - const media = typeof this.options.media === 'string' ? this.options.media : 'all'; - - // { preload:'js', media:true } - // { preload:'js', media:'print' } - if (this.options.media) { - cssLoaderPreamble = cssLoaderPreamble.replace('l.href', "l.media='only x';l.onload=function(){l.media='" + media + "'};l.href"); - } - - // Attempt to read from assets, falling back to a disk read - const sheet = asset ? asset.source() : await this.readFile(filename, 'utf8'); - - // the reduced critical CSS gets injected into a new