postcss-critical-css
Advanced tools
Comparing version 1.0.3 to 2.0.0
212
index.js
@@ -1,211 +0,1 @@ | ||
'use strict'; | ||
var chalk = require('chalk'); | ||
var postcss = require('postcss'); | ||
var cssnano = require('cssnano'); | ||
var fs = require('fs'); | ||
var path = require('path'); | ||
/** | ||
* Throw a warning if a critical selector is used more than once. | ||
* | ||
* @param {array} Array of critical CSS rules. | ||
* @param {selector} Selector to check for. | ||
* @return {string} Console warning. | ||
*/ | ||
function selectorReuseWarning(rules, selector) { | ||
return rules.reduce(function (init, rule) { | ||
if (rule.selector === selector) { | ||
console.warn('Warning: Selector ' + selector + ' is used more than once.'); | ||
} | ||
return rules; | ||
}, []); | ||
} | ||
/** | ||
* Identify critical CSS selectors | ||
* | ||
* @param {obj} PostCSS CSS object. | ||
* @return {object} Object containing critical rules, organized by output destination | ||
*/ | ||
function getCriticalRules(css, preserve) { | ||
var critical = {}; | ||
css.walkDecls('critical-selector', function (decl) { | ||
var dest = getDest(decl.parent); | ||
if ('undefined' === typeof critical[dest]) { | ||
critical[dest] = []; | ||
} | ||
switch (decl.value) { | ||
case 'scope': | ||
var childRules = getChildRules(css, decl.parent, preserve); | ||
selectorReuseWarning(critical[dest], decl.parent.selector); | ||
// Make sure the parent selector contains declarations | ||
if (decl.parent.nodes.length > 1) { | ||
critical[dest].push(decl.parent); | ||
} | ||
// Push all child rules | ||
if (childRules !== null && childRules.length) { | ||
childRules.forEach(function (rule) { | ||
critical[dest].push(rule); | ||
}); | ||
} | ||
break; | ||
case 'this': | ||
selectorReuseWarning(critical[dest], decl.parent.selector); | ||
critical[dest].push(decl.parent); | ||
break; | ||
default: | ||
var container = decl.parent; | ||
container.selector = decl.value.replace(/['"]*/g, ''); | ||
selectorReuseWarning(critical[dest], container.selector); | ||
critical[dest].push(container); | ||
break; | ||
} | ||
decl.remove(); | ||
}); | ||
return critical; | ||
} | ||
/** | ||
* Get rules for selectors nested within parent node | ||
* | ||
* @param {obj} PostCSS CSS object | ||
* @param {object} Parent rule for which children should be included | ||
* @param {bool} Whether or not to keep the critical rule in the stylesheet | ||
*/ | ||
function getChildRules(css, parent, preserve) { | ||
var ruleList = []; | ||
var selectorRegExp = new RegExp(parent.selector); | ||
// Walk all rules to mach child selectors | ||
css.walkRules(selectorRegExp, function (rule) { | ||
var childRule = matchChild(parent, rule); | ||
if (childRule) { | ||
ruleList.push(rule); | ||
} | ||
}); | ||
// Walk all at-rules to match nested child selectors | ||
css.walkAtRules(function (atRule) { | ||
atRule.walkRules(selectorRegExp, function (rule) { | ||
var childRule = matchChild(parent, rule); | ||
// Create new at-rule to append only necessary selector to critical | ||
var criticalAtRule = postcss.atRule({ | ||
name: atRule.name, | ||
params: atRule.params | ||
}); | ||
// Should append even if parent selector | ||
if (rule.selector === parent.selector || childRule) { | ||
criticalAtRule.append(rule); | ||
ruleList.push(criticalAtRule); | ||
if (!preserve) { | ||
rule.remove(); | ||
} | ||
} | ||
}); | ||
}); | ||
return ruleList; | ||
} | ||
/** | ||
* Get rules for selectors nested within parent node | ||
* | ||
* @param {obj} PostCSS CSS object | ||
* @return {object} Parent rule for which children should be included | ||
*/ | ||
function matchChild(parent, rule) { | ||
var childRegExp = new RegExp('(, )?(' + parent.selector + ' [^,\s]*),?.*'); | ||
var childMatch = rule.selector.match(childRegExp); | ||
if (rule.selector !== parent.selector && childMatch !== null) { | ||
return true; | ||
} | ||
return false; | ||
} | ||
/** | ||
* Identify critical CSS destinations. | ||
* | ||
* @param {object} PostCSS rule. | ||
* @return {array} string corresponding to output destination. | ||
*/ | ||
function getDest(selector) { | ||
var dest = 'critical.css'; | ||
selector.walkDecls('critical-filename', function (decl) { | ||
dest = decl.value.replace(/['"]*/g, ''); | ||
decl.remove(); | ||
}); | ||
return dest; | ||
} | ||
/** | ||
* Primary plugin function. | ||
* | ||
* @param {object} array of options. | ||
* @return {function} function for PostCSS plugin. | ||
*/ | ||
function buildCritical(options) { | ||
var args = Object.assign({}, { | ||
outputPath: process.cwd(), | ||
preserve: true, | ||
minify: true, | ||
dryRun: false | ||
}, options); | ||
return function (css, result) { | ||
var criticalOutput = getCriticalRules(css, args.preserve); | ||
var _loop = function _loop(fileName) { | ||
var criticalCSS = postcss.parse(''); | ||
var critical = ''; | ||
var rules = []; | ||
var plugins = args.minify ? [cssnano()] : []; | ||
rules = criticalOutput[fileName].reduce(function (init, rule) { | ||
rule.walkDecls('critical', function (decl) { | ||
decl.remove(); | ||
}); | ||
criticalCSS.append(rule); | ||
if (rule.type === 'rule' && !args.preserve) { | ||
rule.remove(); | ||
} | ||
return criticalOutput[fileName]; | ||
}, {}); | ||
postcss(plugins).process(criticalCSS).then(function (result) { | ||
if (!args.dryRun) { | ||
fs.writeFileSync(path.join(args.outputPath, fileName), result); | ||
} else { | ||
console.log(chalk.green('\nCritical CSS result is:\n' + chalk.yellow(result.css))); | ||
return '\nCritical CSS result is:\n' + result.css; | ||
} | ||
}); | ||
}; | ||
for (var fileName in criticalOutput) { | ||
_loop(fileName); | ||
} | ||
}; | ||
} | ||
module.exports = postcss.plugin('postcss-critical', buildCritical); | ||
module.exports = require('./lib'); |
{ | ||
"name": "postcss-critical-css", | ||
"version": "1.0.3", | ||
"version": "2.0.0", | ||
"description": "Generate critical CSS using PostCSS", | ||
@@ -12,6 +12,8 @@ "main": "index.js", | ||
"postcss-plugin", | ||
"postcss plugin", | ||
"postcss", | ||
"critical-css", | ||
"critical", | ||
"css" | ||
"css", | ||
"critical css" | ||
], | ||
@@ -23,14 +25,34 @@ "author": "Zach Green", | ||
"babel-cli": "^6.11.4", | ||
"babel-eslint": "^6.1.2", | ||
"babel-plugin-transform-flow-strip-types": "^6.8.0", | ||
"babel-plugin-transform-object-rest-spread": "^6.20.2", | ||
"babel-preset-es2015": "^6.13.2", | ||
"chalk": "^1.1.3", | ||
"cssnano": "^3.5.2", | ||
"eslint": "^3.3.1", | ||
"eslint-config-airbnb": "^10.0.1", | ||
"eslint-config-standard": "^6.2.1", | ||
"eslint-plugin-flowtype": "^2.7.1", | ||
"eslint-plugin-import": "^1.13.0", | ||
"eslint-plugin-promise": "^3.4.0", | ||
"eslint-plugin-standard": "^2.0.1", | ||
"flow-bin": "^0.30.0", | ||
"postcss": "^5.0.5", | ||
"postcss-cli": "^2.6.0", | ||
"tape": "^4.6.0" | ||
}, | ||
"scripts": { | ||
"build": "babel src/index.js --out-file index.js", | ||
"start": "babel src/index.js --out-file index.js --watch", | ||
"build": "eslint src/** && npm run flow && babel src --out-dir lib", | ||
"example": "./node_modules/.bin/babel-node example/example.js", | ||
"flow": "flow; test $? -eq 0 -o $? -eq 2", | ||
"eslint": "eslint src/**", | ||
"start": "eslint src/** && npm run flow && babel src/index.js --out-file index.js --watch", | ||
"pretest": "./node_modules/.bin/babel-node test/preTest.js", | ||
"test": "npm run pretest && tape test" | ||
}, | ||
"dependencies": { | ||
"chalk": "^1.1.3", | ||
"cssnano": "^3.7.4", | ||
"postcss": "^5.1.2" | ||
} | ||
} |
136
README.md
# PostCSS Critical CSS | ||
This plugin allows you to define and output critical CSS using custom CSS properties. | ||
This plugin allows the user to define and output critical CSS using custom atRules, and/or custom CSS properties. Critical CSS may be output to one or more files, as defined within the plugin options or within the CSS. | ||
@@ -9,8 +9,13 @@ ## Install | ||
## Example | ||
## Examples | ||
A live example is available in this repo. See the `/example` directory, and use the command `npm run example` to test it out. | ||
### Using the `@critical` atRule | ||
```css | ||
/* In foo.css */ | ||
@critical; | ||
.foo { | ||
critical-selector: this; | ||
border: 3px solid gray; | ||
@@ -31,9 +36,9 @@ display: flex; | ||
Note that in the above example, the selector is rendered as it is written in the | ||
module. This may not be desireable, so you can alternatively identify the | ||
selector you'd like to use in your `critical.css`; | ||
### Using the `@critical` atRule with a custom file path | ||
```css | ||
/* In foo.css */ | ||
@critical bar; | ||
.foo { | ||
critical-selector: .custom-selector; | ||
border: 3px solid gray; | ||
@@ -46,4 +51,4 @@ display: flex; | ||
```css | ||
/* In critical.css */ | ||
.custom-selector { | ||
/* In bar.css */ | ||
.foo { | ||
border: 3px solid gray; | ||
@@ -55,7 +60,7 @@ display: flex; | ||
If you'd like to ouptut the entire scope of a module, including children, you can! | ||
### Using the `@critical` atRule with a subset of styles | ||
```css | ||
/* in foo.css */ | ||
/* In foo.css */ | ||
.foo { | ||
critical-selector: scope; | ||
border: 3px solid gray; | ||
@@ -66,5 +71,7 @@ display: flex; | ||
.foo a { | ||
color: blue; | ||
text-decoration: none; | ||
@critical { | ||
.bar { | ||
border: 10px solid gold; | ||
color: gold; | ||
} | ||
} | ||
@@ -74,2 +81,22 @@ ``` | ||
```css | ||
/* In bar.css */ | ||
.bar { | ||
border: 10px solid gold; | ||
color: gold; | ||
} | ||
``` | ||
### Using the custom property, `critical-selector` | ||
```css | ||
/* In foo.css */ | ||
.foo { | ||
critical-selector: this; | ||
border: 3px solid gray; | ||
display: flex; | ||
padding: 1em; | ||
} | ||
``` | ||
Will output: | ||
```css | ||
/* In critical.css */ | ||
@@ -81,12 +108,27 @@ .foo { | ||
} | ||
``` | ||
.foo a { | ||
color: blue; | ||
text-decoration: none; | ||
### Using the custom property, `critical-selector`, with a custom selector. | ||
```css | ||
/* In foo.css */ | ||
.foo { | ||
critical-selector: .bar; | ||
border: 3px solid gray; | ||
display: flex; | ||
padding: 1em; | ||
} | ||
``` | ||
Will output: | ||
```css | ||
/* In critical.css */ | ||
.bar { | ||
border: 3px solid gray; | ||
display: flex; | ||
padding: 1em; | ||
} | ||
``` | ||
And what if you need to output multiple critical CSS files | ||
(for example, if you have two different templates that do not share styles)? | ||
You can do that as well. | ||
### Using the custom property, `critical-filename` | ||
```css | ||
@@ -112,22 +154,48 @@ /* in foo.css */ | ||
## Options | ||
### Using the custom property, `critical-selector`, with value `scope` | ||
**outputPath** | ||
Path to which critical CSS should be output | ||
Default: current working directory | ||
This allows the user to output the entire scope of a module, including children. | ||
**preserve** | ||
Whether or not to remove selectors from primary CSS document once they've been marked as critical. | ||
This should prevent duplication of selectors across critical and non-critical CSS. | ||
WARNING: this is a destructive option and may break styles relying on the cascade! | ||
Default: true | ||
```css | ||
/* in foo.css */ | ||
.foo { | ||
critical-selector: scope; | ||
border: 3px solid gray; | ||
display: flex; | ||
padding: 1em; | ||
} | ||
**minify** | ||
Minify output CSS | ||
Default: true | ||
.foo a { | ||
color: blue; | ||
text-decoration: none; | ||
} | ||
``` | ||
Will output: | ||
```css | ||
/* In critical.css */ | ||
.foo { | ||
border: 3px solid gray; | ||
display: flex; | ||
padding: 1em; | ||
} | ||
.foo a { | ||
color: blue; | ||
text-decoration: none; | ||
} | ||
``` | ||
## Plugin options | ||
The plugin takes a single object as its only parameter. The following properties are valid: | ||
| Arg | Type | Description | Default | | ||
| ------------ | --------- | ------------------------------------------- | ------------------------- | | ||
| `outputPath` | `string` | Path to which critical CSS should be output | Current working directory | | ||
| `preserve` | `boolean` | Whether or not to remove selectors from primary CSS document once they've been marked as critical. This should prevent duplication of selectors across critical and non-critical CSS. | `true` | | ||
| `minify` | `boolean` | Minify output CSS? | `true` | | ||
## To Dos | ||
- Tests | ||
- More tests | ||
- More robust warnings |
231
src/index.js
@@ -1,161 +0,11 @@ | ||
'use strict'; | ||
// @flow | ||
const chalk = require('chalk'); | ||
var postcss = require('postcss'); | ||
var cssnano = require('cssnano'); | ||
var fs = require('fs'); | ||
var path = require('path'); | ||
import chalk from 'chalk' | ||
import postcss from 'postcss' | ||
import cssnano from 'cssnano' | ||
import fs from 'fs' | ||
import path from 'path' | ||
import { getCriticalRules } from './getCriticalRules' | ||
/** | ||
* Throw a warning if a critical selector is used more than once. | ||
* | ||
* @param {array} Array of critical CSS rules. | ||
* @param {selector} Selector to check for. | ||
* @return {string} Console warning. | ||
*/ | ||
function selectorReuseWarning(rules, selector) { | ||
return rules.reduce((init, rule) => { | ||
if (rule.selector === selector) { | ||
console.warn(`Warning: Selector ${selector} is used more than once.`); | ||
} | ||
return rules; | ||
}, []); | ||
} | ||
/** | ||
* Identify critical CSS selectors | ||
* | ||
* @param {obj} PostCSS CSS object. | ||
* @return {object} Object containing critical rules, organized by output destination | ||
*/ | ||
function getCriticalRules(css, preserve) { | ||
let critical = {}; | ||
css.walkDecls('critical-selector', decl => { | ||
let dest = getDest(decl.parent); | ||
if ('undefined' === typeof critical[dest]) { | ||
critical[dest] = []; | ||
} | ||
switch (decl.value) { | ||
case 'scope': | ||
let childRules = getChildRules(css, decl.parent, preserve); | ||
selectorReuseWarning(critical[dest], decl.parent.selector); | ||
// Make sure the parent selector contains declarations | ||
if (decl.parent.nodes.length > 1) { | ||
critical[dest].push(decl.parent); | ||
} | ||
// Push all child rules | ||
if (childRules !== null && childRules.length) { | ||
childRules.forEach(rule => { | ||
critical[dest].push(rule); | ||
}); | ||
} | ||
break; | ||
case 'this': | ||
selectorReuseWarning(critical[dest], decl.parent.selector); | ||
critical[dest].push(decl.parent); | ||
break; | ||
default: | ||
const container = decl.parent; | ||
container.selector = decl.value.replace(/['"]*/g, ''); | ||
selectorReuseWarning(critical[dest], container.selector); | ||
critical[dest].push(container); | ||
break; | ||
} | ||
decl.remove(); | ||
}); | ||
return critical; | ||
} | ||
/** | ||
* Get rules for selectors nested within parent node | ||
* | ||
* @param {obj} PostCSS CSS object | ||
* @param {object} Parent rule for which children should be included | ||
* @param {bool} Whether or not to keep the critical rule in the stylesheet | ||
*/ | ||
function getChildRules(css, parent, preserve) { | ||
let ruleList = []; | ||
let selectorRegExp = new RegExp(parent.selector); | ||
// Walk all rules to mach child selectors | ||
css.walkRules(selectorRegExp, rule => { | ||
let childRule = matchChild(parent, rule); | ||
if (childRule) { | ||
ruleList.push(rule); | ||
} | ||
}); | ||
// Walk all at-rules to match nested child selectors | ||
css.walkAtRules(atRule => { | ||
atRule.walkRules(selectorRegExp, rule => { | ||
let childRule = matchChild(parent, rule); | ||
// Create new at-rule to append only necessary selector to critical | ||
let criticalAtRule = postcss.atRule({ | ||
name: atRule.name, | ||
params: atRule.params | ||
}); | ||
// Should append even if parent selector | ||
if (rule.selector === parent.selector || childRule) { | ||
criticalAtRule.append(rule); | ||
ruleList.push(criticalAtRule); | ||
if (!preserve) { | ||
rule.remove(); | ||
} | ||
} | ||
}); | ||
}); | ||
return ruleList; | ||
} | ||
/** | ||
* Get rules for selectors nested within parent node | ||
* | ||
* @param {obj} PostCSS CSS object | ||
* @return {object} Parent rule for which children should be included | ||
*/ | ||
function matchChild(parent, rule) { | ||
let childRegExp = new RegExp('(, )?(' + parent.selector + ' [^,\s]*),?.*'); | ||
let childMatch = rule.selector.match(childRegExp); | ||
if (rule.selector !== parent.selector && childMatch !== null) { | ||
return true; | ||
} | ||
return false; | ||
} | ||
/** | ||
* Identify critical CSS destinations. | ||
* | ||
* @param {object} PostCSS rule. | ||
* @return {array} string corresponding to output destination. | ||
*/ | ||
function getDest(selector) { | ||
let dest = 'critical.css'; | ||
selector.walkDecls('critical-filename', decl => { | ||
dest = decl.value.replace(/['"]*/g, ''); | ||
decl.remove(); | ||
}); | ||
return dest; | ||
} | ||
/** | ||
* Primary plugin function. | ||
@@ -166,52 +16,43 @@ * | ||
*/ | ||
function buildCritical(options) { | ||
const args = Object.assign({}, | ||
{ | ||
type ArgsType = { | ||
outputPath: string, | ||
preserve: boolean, | ||
minify: boolean, | ||
dryRun: boolean | ||
} | ||
function buildCritical (options: ArgsType): Function { | ||
const args = { | ||
outputPath: process.cwd(), | ||
preserve: true, | ||
minify: true, | ||
dryRun: false | ||
}, options); | ||
return (css, result) => { | ||
let criticalOutput = getCriticalRules(css, args.preserve); | ||
for (let fileName in criticalOutput) { | ||
let criticalCSS = postcss.parse(''); | ||
let critical = ''; | ||
let rules = []; | ||
let plugins = args.minify ? [cssnano()] : []; | ||
rules = criticalOutput[fileName].reduce((init, rule) => { | ||
rule.walkDecls('critical', (decl) => { | ||
decl.remove(); | ||
}); | ||
criticalCSS.append(rule); | ||
if (rule.type === 'rule' && !args.preserve) { | ||
rule.remove(); | ||
} | ||
return criticalOutput[fileName]; | ||
}, {}); | ||
postcss(plugins) | ||
dryRun: false, | ||
...options | ||
} | ||
return (css: Object): Object => { | ||
let criticalOutput = getCriticalRules(css, args.preserve) | ||
return Object.keys(criticalOutput).reduce((init: Object, cur: string): Object => { | ||
const criticalCSS = postcss.root() | ||
criticalCSS.append(criticalOutput[cur]) | ||
postcss(args.minify ? [cssnano()] : []) | ||
.process(criticalCSS) | ||
.then(result => { | ||
.then((result: Object) => { | ||
if (!args.dryRun) { | ||
fs.writeFileSync(path.join(args.outputPath, fileName), result); | ||
fs.writeFile( | ||
path.join(args.outputPath, cur), | ||
result.css | ||
) | ||
} else { | ||
console.log( | ||
console.log( // eslint-disable-line no-console | ||
chalk.green(` | ||
Critical CSS result is: | ||
${chalk.yellow(result.css)}`) | ||
); | ||
return ` | ||
Critical CSS result is: | ||
${result.css}`; | ||
) | ||
} | ||
}); | ||
} | ||
}) | ||
return criticalOutput | ||
}, {}) | ||
} | ||
} | ||
module.exports = postcss.plugin('postcss-critical', buildCritical); | ||
module.exports = postcss.plugin('postcss-critical', buildCritical) |
@@ -10,46 +10,62 @@ #!/usr/bin/env node | ||
function fixturePath(name) { | ||
return 'test/fixtures/' + name + '.css'; | ||
function compareCritical(t, name, testNonCritical) { | ||
t.equal( | ||
fs.readFileSync( | ||
`${basePath}/${name}.${testNonCritical ? 'non-critical.actual' : 'critical.actual'}.css`, 'utf8' | ||
).trim(), | ||
fs.readFileSync( | ||
`${basePath}/${name}.${testNonCritical ? 'non-critical.expected' : 'critical.expected'}.css`, 'utf8' | ||
).trim(), | ||
`processed fixture ${chalk.bold(name)} should be equal to expected output` | ||
); | ||
} | ||
function fixture(name) { | ||
return fs.readFileSync(fixturePath(name), 'utf8').trim(); | ||
} | ||
test('Testing "this" critical result', function(t) { | ||
compareCritical(t, 'this'); | ||
t.end(); | ||
}); | ||
function resolveFixture(name, options) { | ||
return postcss(postcssCriticalCSS(options)) | ||
.process(fixture(name), {from: fixturePath(name)}); | ||
} | ||
test('Testing "this" non-critical result', function(t) { | ||
compareCritical(t, 'this', true); | ||
t.end(); | ||
}); | ||
function compareFixtures(t, name, options) { | ||
var postcssResult = resolveFixture(name, options); | ||
var actual = postcssResult.css.trim(); | ||
test('Testing "atRule" critical result', function(t) { | ||
compareCritical(t, 'atRule'); | ||
t.end(); | ||
}); | ||
fs.writeFile(fixturePath(name + '.actual'), actual); | ||
test('Testing "atRule" non-critical result', function(t) { | ||
compareCritical(t, 'atRule', true); | ||
t.end(); | ||
}); | ||
var expected = fixture(name + '.expected'); | ||
t.equal( | ||
actual, expected, | ||
'processed fixture ' + chalk.bold(name) + ' should be equal to expected output' | ||
); | ||
test(chalk.yellow(`Testing ${chalk.bold('atRule.wrapping')} critical result`), function(t) { | ||
compareCritical(t, 'atRule-wrapping'); | ||
t.end(); | ||
}); | ||
return postcssResult; | ||
} | ||
test(chalk.yellow(`Testing ${chalk.bold('atRule.wrapping')} non-critical result`), function(t) { | ||
compareCritical(t, 'atRule-wrapping', true); | ||
t.end(); | ||
}); | ||
function compareCritical(t, name) { | ||
t.equal( | ||
fs.readFileSync(`${basePath}/${name}.critical.actual.css`, 'utf8').trim(), | ||
fs.readFileSync(`${basePath}/${name}.critical.expected.css`, 'utf8').trim(), | ||
`processed fixture ${chalk.bold(name)} should be equal to expected output` | ||
); | ||
} | ||
test('Testing "media" critical result', function(t) { | ||
compareCritical(t, 'media'); | ||
t.end(); | ||
}); | ||
test('Testing "this" critical result', function(t) { | ||
compareCritical(t, 'this'); | ||
test('Testing "media" non-critical result', function(t) { | ||
compareCritical(t, 'media', true); | ||
t.end(); | ||
}); | ||
test('Testing "this" non-critical result', function(t) { | ||
compareFixtures(t, 'this'); | ||
test(chalk.yellow(`Testing ${chalk.bold('scope')} critical result`), function(t) { | ||
compareCritical(t, 'scope'); | ||
t.end(); | ||
}); | ||
test(chalk.yellow(`Testing ${chalk.bold('scope')} non-critical result`), function(t) { | ||
compareCritical(t, 'scope', true); | ||
t.end(); | ||
}); |
@@ -8,9 +8,28 @@ #!/usr/bin/env node | ||
const basePath = `${process.cwd()}/test/fixtures`; | ||
const files = fs.readdirSync(basePath, 'utf8'); | ||
files.forEach(function(file) { | ||
if (file.indexOf('.expected') === -1 && file.indexOf('.actual') === -1) { | ||
postcss(postcssCriticalCSS({outputPath: basePath})) | ||
.process(fs.readFileSync(`${basePath}/${file}`, 'utf8') | ||
.trim()); | ||
function cb (files) { | ||
function useFileData (data, file) { | ||
postcss([postcssCriticalCSS({outputPath: basePath})]) | ||
.process(data) | ||
.then(result => fs.writeFile(`${basePath}/${file.split('.')[0]}.non-critical.actual.css`, result.css)) | ||
} | ||
}); | ||
files.forEach(function(file) { | ||
if (file.indexOf('.actual') !== -1) { | ||
fs.unlink(`${basePath}/${file}`) | ||
} | ||
if (file.indexOf('.expected') === -1 && file.indexOf('.actual') === -1) { | ||
fs.readFile(`${basePath}/${file}`, 'utf8', (err, data) => { | ||
if (err) { | ||
throw new Error(err) | ||
} | ||
useFileData(data, file) | ||
}) | ||
} | ||
}) | ||
} | ||
fs.readdir(basePath, 'utf8', (err, files) => { | ||
if (err) { | ||
throw new Error(err) | ||
} | ||
cb(files) | ||
}) |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
26463
54
637
194
3
19
5
1
+ Addedchalk@^1.1.3
+ Addedcssnano@^3.7.4
+ Addedpostcss@^5.1.2
+ Addedalphanum-sort@1.0.2(transitive)
+ Addedansi-regex@2.1.1(transitive)
+ Addedansi-styles@2.2.1(transitive)
+ Addedargparse@1.0.10(transitive)
+ Addedautoprefixer@6.7.7(transitive)
+ Addedbalanced-match@0.4.21.0.2(transitive)
+ Addedbrowserslist@1.7.7(transitive)
+ Addedcaniuse-api@1.6.1(transitive)
+ Addedcaniuse-db@1.0.30001620(transitive)
+ Addedchalk@1.1.3(transitive)
+ Addedclap@1.2.3(transitive)
+ Addedclone@1.0.4(transitive)
+ Addedcoa@1.0.4(transitive)
+ Addedcolor@0.11.4(transitive)
+ Addedcolor-convert@1.9.3(transitive)
+ Addedcolor-name@1.1.3(transitive)
+ Addedcolor-string@0.3.0(transitive)
+ Addedcolormin@1.1.2(transitive)
+ Addedcolors@1.1.2(transitive)
+ Addedcss-color-names@0.0.4(transitive)
+ Addedcssnano@3.10.0(transitive)
+ Addedcsso@2.3.2(transitive)
+ Addeddecamelize@1.2.0(transitive)
+ Addeddefined@1.0.1(transitive)
+ Addedescape-string-regexp@1.0.5(transitive)
+ Addedesprima@2.7.3(transitive)
+ Addedflatten@1.0.3(transitive)
+ Addedhas@1.0.4(transitive)
+ Addedhas-ansi@2.0.0(transitive)
+ Addedhas-flag@1.0.0(transitive)
+ Addedhtml-comment-regex@1.1.2(transitive)
+ Addedindexes-of@1.0.1(transitive)
+ Addedis-absolute-url@2.1.0(transitive)
+ Addedis-plain-obj@1.1.0(transitive)
+ Addedis-svg@2.1.0(transitive)
+ Addedjs-base64@2.6.4(transitive)
+ Addedjs-yaml@3.7.0(transitive)
+ Addedlodash.memoize@4.1.2(transitive)
+ Addedlodash.uniq@4.5.0(transitive)
+ Addedmath-expression-evaluator@1.4.0(transitive)
+ Addedminimist@1.2.8(transitive)
+ Addedmkdirp@0.5.6(transitive)
+ Addednormalize-range@0.1.2(transitive)
+ Addednormalize-url@1.9.1(transitive)
+ Addednum2fraction@1.2.2(transitive)
+ Addedobject-assign@4.1.1(transitive)
+ Addedpostcss@5.2.18(transitive)
+ Addedpostcss-calc@5.3.1(transitive)
+ Addedpostcss-colormin@2.2.2(transitive)
+ Addedpostcss-convert-values@2.6.1(transitive)
+ Addedpostcss-discard-comments@2.0.4(transitive)
+ Addedpostcss-discard-duplicates@2.1.0(transitive)
+ Addedpostcss-discard-empty@2.1.0(transitive)
+ Addedpostcss-discard-overridden@0.1.1(transitive)
+ Addedpostcss-discard-unused@2.2.3(transitive)
+ Addedpostcss-filter-plugins@2.0.3(transitive)
+ Addedpostcss-merge-idents@2.1.7(transitive)
+ Addedpostcss-merge-longhand@2.0.2(transitive)
+ Addedpostcss-merge-rules@2.1.2(transitive)
+ Addedpostcss-message-helpers@2.0.0(transitive)
+ Addedpostcss-minify-font-values@1.0.5(transitive)
+ Addedpostcss-minify-gradients@1.0.5(transitive)
+ Addedpostcss-minify-params@1.2.2(transitive)
+ Addedpostcss-minify-selectors@2.1.1(transitive)
+ Addedpostcss-normalize-charset@1.1.1(transitive)
+ Addedpostcss-normalize-url@3.0.8(transitive)
+ Addedpostcss-ordered-values@2.2.3(transitive)
+ Addedpostcss-reduce-idents@2.4.0(transitive)
+ Addedpostcss-reduce-initial@1.0.1(transitive)
+ Addedpostcss-reduce-transforms@1.0.4(transitive)
+ Addedpostcss-selector-parser@2.2.3(transitive)
+ Addedpostcss-svgo@2.1.6(transitive)
+ Addedpostcss-unique-selectors@2.0.2(transitive)
+ Addedpostcss-value-parser@3.3.1(transitive)
+ Addedpostcss-zindex@2.2.0(transitive)
+ Addedprepend-http@1.0.4(transitive)
+ Addedq@1.5.1(transitive)
+ Addedquery-string@4.3.4(transitive)
+ Addedreduce-css-calc@1.3.0(transitive)
+ Addedreduce-function-call@1.0.3(transitive)
+ Addedsax@1.2.4(transitive)
+ Addedsort-keys@1.1.2(transitive)
+ Addedsource-map@0.5.7(transitive)
+ Addedsprintf-js@1.0.3(transitive)
+ Addedstrict-uri-encode@1.1.0(transitive)
+ Addedstrip-ansi@3.0.1(transitive)
+ Addedsupports-color@2.0.03.2.3(transitive)
+ Addedsvgo@0.7.2(transitive)
+ Addeduniq@1.0.1(transitive)
+ Addeduniqs@2.0.0(transitive)
+ Addedvendors@1.0.4(transitive)
+ Addedwhet.extend@0.9.9(transitive)