Socket
Socket
Sign inDemoInstall

critical

Package Overview
Dependencies
Maintainers
3
Versions
111
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

critical - npm Package Compare versions

Comparing version 1.3.4 to 2.0.0-0

src/array.js

742

CHANGELOG.md

@@ -0,478 +1,444 @@

# v2.0.0 / 2018-11-27
v1.3.4 / 2018-07-19
==================
- Drop support for node < 8
- Bump dependencies
- Use Jest for testing
- Drop `include` and `timeout` options as they can be specified in the `penthouse` options.
- Drop options `styleTarget` & `dest` in favour of `target`
You can specify either a **css** file, a **html** file or an object `{css: dest.css, html: dest.html}` if you want to store both. We may also add an extract target here in a future release.
- Drop options `destFolder`, `folder` and `pathPrefix`. We tried our best to improve the way critical auto-detects the paths to used assets in the critical css which should suit for most cases. If this doesn't work out you can use the new `rebase` option to either specify the location of the css & the html file like this: `{from: '/styles/main.css', to: '/en/test.html'}`. You can also pass a callback function to dynamically compute the path or specify a cdn for example. We utilize [`postcss-url`](https://github.com/postcss/postcss-url#options-list) for this task.
- Due to some limitations with modern css features we replaced `filter-css` as the library of choice for handling ignores with [postcss-discard](https://github.com/bezoerb/postcss-discard/). We tried to keep things backwards compatible but you may have to change your `ignore` configuration.
- Add `concurrency` option to specify how many operations can run in parallel.
- Add the ability to specify used css files using file globs. See supported `minimatch` [patterns](https://github.com/isaacs/minimatch#usage).
* fix: return Promise.reject instead of re-throw
* fix: handle PAGE_UNLOADED_DURING_EXECUTION error (#314)
* output warning on invalid extract setting
* Add user agent option (#316)
* Bump dependencies
* npm audit fix
# v1.3.4 / 2018-07-19
v1.3.3 / 2018-06-06
===================
- fix: return Promise.reject instead of re-throw
- fix: handle PAGE_UNLOADED_DURING_EXECUTION error (#314)
- output warning on invalid extract setting
- Add user agent option (#316)
- Bump dependencies
- npm audit fix
* Bump dependencies
* Docs: fix typo (#310)
* Reduced vulnerabilities [#308]
# v1.3.3 / 2018-06-06
v1.3.2 / 2018-05-15
==================
- Bump dependencies
- Docs: fix typo (#310)
- Reduced vulnerabilities [#308]
* switched to async-exit-hook
# v1.3.2 / 2018-05-15
v1.3.1 / 2018-05-14
==================
- switched to async-exit-hook
* Bump dependencies
* Removed process.exit on cleanup
* Adding html-webpack-critical-plugin to README (#306)
# v1.3.1 / 2018-05-14
v1.3.0 / 2018-05-02
===================
- Bump dependencies
- Removed process.exit on cleanup
- Adding html-webpack-critical-plugin to README (#306)
* Add basic auth option [#295]
# v1.3.0 / 2018-05-02
v1.2.2 / 2018-04-02
===================
- Add basic auth option [#295]
* Improved handling of protocol-relative asset urls [#288]
* Adjust test files according to [#293]
* Improve error reporting [#258]
* Replace gutil by fancy-log [#297]
* Update README.md [#296]
# v1.2.2 / 2018-04-02
v1.2.1 / 2018-03-26
===================
- Improved handling of protocol-relative asset urls [#288]
- Adjust test files according to [#293]
- Improve error reporting [#258]
- Replace gutil by fancy-log [#297]
- Update README.md [#296]
* Add license file
# v1.2.1 / 2018-03-26
v1.2.0 / 2018-03-19
===================
- Add license file
* Allow external stylesheets passed as css option [#290]
* Add Tests for #277
# v1.2.0 / 2018-03-19
v1.1.1 / 2018-03-15
==================
- Allow external stylesheets passed as css option [#290]
- Add Tests for #277
* Bump dependencies
# v1.1.1 / 2018-03-15
v1.1.0 / 2017-12-02
===================
- Bump dependencies
* 1.1.0
* Remove temporary files
* Bump inline-critical
* Fix corrupted 'File.contents' [#191,#218]
# v1.1.0 / 2017-12-02
v1.0.0 / 2017-11-06
===================
- 1.1.0
- Remove temporary files
- Bump inline-critical
- Fix corrupted 'File.contents' [#191,#218]
* 1.0.0
* Bump dependencies
* Removed deprecated methods
* Don't enforce strict SSL for external assets [#171]
* Allow http 2xx response codes [#244]
* Replace '|' with its HTML character entity reference (#248)
* Headless chrome (#246)
* Add "folder" option to readme [#245]
# v1.0.0 / 2017-11-06
n.n.n / 2017-12-02
==================
- 1.0.0
- Bump dependencies
- Removed deprecated methods
- Don't enforce strict SSL for external assets [#171]
- Allow http 2xx response codes [#244]
- Replace '|' with its HTML character entity reference (#248)
- Headless chrome (#246)
- Add "folder" option to readme [#245]
# n.n.n / 2017-12-02
v1.0.0 / 2017-11-06
===================
# v1.0.0 / 2017-11-06
* 1.0.0
* Bump dependencies
* Removed deprecated methods
* Don't enforce strict SSL for external assets [#171]
* Allow http 2xx response codes [#244]
* Replace '|' with its HTML character entity reference (#248)
* Headless chrome (#246)
* Add "folder" option to readme [#245]
- 1.0.0
- Bump dependencies
- Removed deprecated methods
- Don't enforce strict SSL for external assets [#171]
- Allow http 2xx response codes [#244]
- Replace '|' with its HTML character entity reference (#248)
- Headless chrome (#246)
- Add "folder" option to readme [#245]
v0.9.1 / 2017-09-04
===================
# v0.9.1 / 2017-09-04
* 0.9.1
* Appveyor tweaks
* Use yarn with appveyor
* some appveyor tweaks
* Added package missing in appveyor
* Remove appveyor cache
* Try to reinstall "css" dependencies
* Upgrade Penthouse
* Update readme according to #220
* Version bump
- 0.9.1
- Appveyor tweaks
- Use yarn with appveyor
- some appveyor tweaks
- Added package missing in appveyor
- Remove appveyor cache
- Try to reinstall "css" dependencies
- Upgrade Penthouse
- Update readme according to #220
- Version bump
v0.9.0 / 2017-07-19
===================
# v0.9.0 / 2017-07-19
* Bump dependencies
* Library options (#178)
* Ignore print styles (#113) (#221)
* Prefer let & const + arrow functions
* Run tests on node.js 8
* Support for passing CSS files as Vinyl objects. (#204)
- Bump dependencies
- Library options (#178)
- Ignore print styles (#113) (#221)
- Prefer let & const + arrow functions
- Run tests on node.js 8
- Support for passing CSS files as Vinyl objects. (#204)
v0.8.4 / 2017-03-01
==================
# v0.8.4 / 2017-03-01
* Better remote handling (#198)
* Bump inline-critical
- Better remote handling (#198)
- Bump inline-critical
v0.8.3 / 2017-02-17
===================
# v0.8.3 / 2017-02-17
* Fixed multi-dimension critical-path CSS
- Fixed multi-dimension critical-path CSS
v0.8.2 / 2017-02-11
===================
# v0.8.2 / 2017-02-11
* Bump dependencies
* Update README.md
- Bump dependencies
- Update README.md
v0.8.1 / 2016-11-24
==================
# v0.8.1 / 2016-11-24
* Added missing comma
* Add tmpfile to garbage collector
* Bump dependencies
* Vinyl (#120)
- Added missing comma
- Add tmpfile to garbage collector
- Bump dependencies
- Vinyl (#120)
v0.8.0 / 2016-08-30
===================
# v0.8.0 / 2016-08-30
* Revise production-use messaging.
* Consistent CSS capitalization in README.
* Remove object.assign; require node.js 4.
* Fix all tests to run on Windows.
* Enforce LF.
* Fix xo errors.
* Update dependencies.
* Fix test failures. (#155)
* Travis: add explicitly node.js 4 and 6. (#154)
* Update .gitignore.
* package.json: remove duplicate dep. (#153)
* Remove JSHint leftovers. (#152)
* Update README.md (#151)
* Update appveyor.yml (#150)
* added penthouse timeout option (#140)
* CSS Rel Preload support (#129)
- Revise production-use messaging.
- Consistent CSS capitalization in README.
- Remove object.assign; require node.js 4.
- Fix all tests to run on Windows.
- Enforce LF.
- Fix xo errors.
- Update dependencies.
- Fix test failures. (#155)
- Travis: add explicitly node.js 4 and 6. (#154)
- Update .gitignore.
- package.json: remove duplicate dep. (#153)
- Remove JSHint leftovers. (#152)
- Update README.md (#151)
- Update appveyor.yml (#150)
- added penthouse timeout option (#140)
- CSS Rel Preload support (#129)
v0.7.3 / 2016-05-30
===================
# v0.7.3 / 2016-05-30
* Bump package.json version
* Add test for 404 case
* Remove trailing whitespace
* Fix silly typo
* Ignore 404 requests, reject promise with Error not String
* Fixed #130
* Better error message for unresolved css files
* cli: exit after stdout.write
* Remove uncaughtException listener log error instead
* Fixed import-order
* Bump dependencies
* Added changelog (#123)
- Bump package.json version
- Add test for 404 case
- Remove trailing whitespace
- Fix silly typo
- Ignore 404 requests, reject promise with Error not String
- Fixed #130
- Better error message for unresolved css files
- cli: exit after stdout.write
- Remove uncaughtException listener log error instead
- Fixed import-order
- Bump dependencies
- Added changelog (#123)
v0.7.2 / 2016-03-17
===================
# v0.7.2 / 2016-03-17
* Add include option (#125)
- Add include option (#125)
v0.7.1 / 2016-02-26
===================
# v0.7.1 / 2016-02-26
* Dropped jshint and added xo
* Adjust tests for penthouse 0.8.4
* Bump dependencies
* Remove listeners on exit
* Update Readme
- Dropped jshint and added xo
- Adjust tests for penthouse 0.8.4
- Bump dependencies
- Remove listeners on exit
- Update Readme
v0.7.0 / 2015-12-22
===================
# v0.7.0 / 2015-12-22
* bump penthouse
* Test #79
* some debug logs
* trigger cleanup
* added missing deps
* Switch to http server for local files (#94)
* ignore generated css
* tests adjusted for penthouse 0.7.1
* minor tweaks
* Fix appveyor tests
* local url for phantomjs (#94)
* penthouse bump
* Bump dependencies
* Bump inline-critical
* Update README.md
* use default base
* add a test for query string in file name
* fix local files query string ENOENT exception
* fixed tests for bumped deps
* Bump dependencies
* appveyor file tweaks
* Actually Emit Critical Error in Stream
* cleanup
* Switched postcss-image-inliner
* bump inline-critical
* appveyor tweaks
* cleanup
* added gc to address #82
* Added cli remote test
* some cleanup
* fixed phantom on missing file extension
* use loadCSS 0.1.8
* allow remote resources
* Hey, man
* Bump dependencies
- bump penthouse
- Test #79
- some debug logs
- trigger cleanup
- added missing deps
- Switch to http server for local files (#94)
- ignore generated css
- tests adjusted for penthouse 0.7.1
- minor tweaks
- Fix appveyor tests
- local url for phantomjs (#94)
- penthouse bump
- Bump dependencies
- Bump inline-critical
- Update README.md
- use default base
- add a test for query string in file name
- fix local files query string ENOENT exception
- fixed tests for bumped deps
- Bump dependencies
- appveyor file tweaks
- Actually Emit Critical Error in Stream
- cleanup
- Switched postcss-image-inliner
- bump inline-critical
- appveyor tweaks
- cleanup
- added gc to address #82
- Added cli remote test
- some cleanup
- fixed phantom on missing file extension
- use loadCSS 0.1.8
- allow remote resources
- Hey, man
- Bump dependencies
v0.6.0 / 2015-07-07
===================
# v0.6.0 / 2015-07-07
* added testcase for #88
* testcase for bc53420 issue
* Fixed issue from bc53420
* Update README.md
* backwards compatibility
* drop node 0.10
* simplify cli help creation
* minor style tweaks
* Merged master
* Fixed tests & locked clean-css version
* Bump filter-css
* Fixed CLI tests
* minor package.json tweaks
* Bump devDependencies
* Correct expectation for adaptive
* Updated tests for new clean-css 3.2.7
* some cleanup
* Bump dependencies
* Update README.md
* Don't encode entities
* Removed parallel testcase
* Add 'ignore' option
* Deprecated some things
* deprecated htmltarget & styletarget for CLI and introduced --inline
* Added pathPrefix support for CLI
* normalize newlines
* added test for pathPrefix option
* allows pathPrefix to be set through options. Updates README
* Added stream wrapper
- added testcase for #88
- testcase for bc53420 issue
- Fixed issue from bc53420
- Update README.md
- backwards compatibility
- drop node 0.10
- simplify cli help creation
- minor style tweaks
- Merged master
- Fixed tests & locked clean-css version
- Bump filter-css
- Fixed CLI tests
- minor package.json tweaks
- Bump devDependencies
- Correct expectation for adaptive
- Updated tests for new clean-css 3.2.7
- some cleanup
- Bump dependencies
- Update README.md
- Don't encode entities
- Removed parallel testcase
- Add 'ignore' option
- Deprecated some things
- deprecated htmltarget & styletarget for CLI and introduced --inline
- Added pathPrefix support for CLI
- normalize newlines
- added test for pathPrefix option
- allows pathPrefix to be set through options. Updates README
- Added stream wrapper
v0.5.7 / 2015-04-12
===================
# v0.5.7 / 2015-04-12
* appveyor tweaks
* Automated windows tests using appveyor
* Fixed tests on windows
* Added some badges
* Bump dependencies
* cleancss syntax change
* modified tests to use new cleancss output
- appveyor tweaks
- Automated windows tests using appveyor
- Fixed tests on windows
- Added some badges
- Bump dependencies
- cleancss syntax change
- modified tests to use new cleancss output
v0.5.6 / 2015-03-16
===================
# v0.5.6 / 2015-03-16
* catch cancellation
* Fix callbacks on error
- catch cancellation
- Fix callbacks on error
v0.5.5 / 2015-03-03
===================
# v0.5.5 / 2015-03-03
* Fixed CLI error codes
* renaming
* Added jshint
* Added tests for #63 & #64
* Bump dependencies
* up dimensions used in tests, update expected result files
* fix typo
* up dimensions used for generate in index.js
* up dimensions used in README examples
* Fix multi test
* bump dependency
* fix #67
* Add support for multi-dimension critical css.
* improve file structure
* readme tweaks
* fix .gitignore
* codestyle
* Bump dependencies
* updated tests for penthouse 0.3.0
- Fixed CLI error codes
- renaming
- Added jshint
- Added tests for #63 & #64
- Bump dependencies
- up dimensions used in tests, update expected result files
- fix typo
- up dimensions used for generate in index.js
- up dimensions used in README examples
- Fix multi test
- bump dependency
- fix #67
- Add support for multi-dimension critical css.
- improve file structure
- readme tweaks
- fix .gitignore
- codestyle
- Bump dependencies
- updated tests for penthouse 0.3.0
v0.5.4 / 2015-02-09
===================
# v0.5.4 / 2015-02-09
* Update .travis.yml
* Use os.tmpdir() folder for temporary css
* add `preferGlobal` prop to package.json
- Update .travis.yml
- Use os.tmpdir() folder for temporary css
- add `preferGlobal` prop to package.json
v0.5.3 / 2015-01-18
===================
# v0.5.3 / 2015-01-18
* Bump dependencies
- Bump dependencies
v0.5.2 / 2015-01-12
===================
# v0.5.2 / 2015-01-12
* #56 Locked penthouse version
- #56 Locked penthouse version
v0.5.1 / 2014-12-28
===================
# v0.5.1 / 2014-12-28
* Fixed tests
* 'inline-critical' version bump
* Fixed CLI Tests for Windows
* Added tests and additional CLI fixes for #52
* Fix for #52
- Fixed tests
- 'inline-critical' version bump
- Fixed CLI Tests for Windows
- Added tests and additional CLI fixes for #52
- Fix for #52
v0.5.0 / 2014-11-28
===================
# v0.5.0 / 2014-11-28
* inline critical version bump
* Increased mocha timeout
* Fixed newline character in css to address #14
* Updated version of inline-critical to address #14
* Added bin/critical to files #49
* added cli / changed structure
* Update README.md
* Remove inlined CSS rules from source stylesheets #39
* Fixed backslash in rebased paths on windows
* fixed fa77c44
* Return critical css even if unlinking of the temporary file fails
* Ignores external stylesheets
- inline critical version bump
- Increased mocha timeout
- Fixed newline character in css to address #14
- Updated version of inline-critical to address #14
- Added bin/critical to files #49
- added cli / changed structure
- Update README.md
- Remove inlined CSS rules from source stylesheets #39
- Fixed backslash in rebased paths on windows
- fixed fa77c44
- Return critical css even if unlinking of the temporary file fails
- Ignores external stylesheets
v0.4.0 / 2014-10-04
===================
# v0.4.0 / 2014-10-04
* Add build tasks
* Update UUID dep
* Changed inlineImages default to false
* Fixed tests for #35
- Add build tasks
- Update UUID dep
- Changed inlineImages default to false
- Fixed tests for #35
v0.3.1 / 2014-09-16
===================
# v0.3.1 / 2014-09-16
* Fixed parallel calls mentioned in #34
- Fixed parallel calls mentioned in #34
v0.3.0 / 2014-09-09
===================
# v0.3.0 / 2014-09-09
* Update fixtures to account for dep. bump
* Bump dependencies
- Update fixtures to account for dep. bump
- Bump dependencies
v0.2.0 / 2014-08-30
===================
# v0.2.0 / 2014-08-30
* fixed implementation in #30
* Skipped max size for inlined images
* Added image inlining to generate
* removed dynamic test file
* Adds a maxImageFileSize for inlined images and rebases relative css resource paths
- fixed implementation in #30
- Skipped max size for inlined images
- Added image inlining to generate
- removed dynamic test file
- Adds a maxImageFileSize for inlined images and rebases relative css resource paths
v0.1.6 / 2014-07-30
===================
# v0.1.6 / 2014-07-30
* Update to Penthouse 0.2.5 to addr raised issues
* change penthouse test to critical css test
* some code formatting
* Fixed tests
* fixed fixtures
* changed test size to only include header nav
* prevent catching callback test errors
* Format code
* Make CSS files/path configurable
* CSS Images fix
* Add more demo projects.
* Add demo projects.
* Move viewport settings up.
* Improve formatting of first example.
- Update to Penthouse 0.2.5 to addr raised issues
- change penthouse test to critical css test
- some code formatting
- Fixed tests
- fixed fixtures
- changed test size to only include header nav
- prevent catching callback test errors
- Format code
- Make CSS files/path configurable
- CSS Images fix
- Add more demo projects.
- Add demo projects.
- Move viewport settings up.
- Improve formatting of first example.
v0.1.5 / 2014-07-16
===================
# v0.1.5 / 2014-07-16
* Improve the Critical / Penthouse section
* Readme corrections
* Add contributing guide
* Readme revisions
* Add mention of criticalCSS module.
* More edits
* Infra revisions
* Add note about unit tests.
* Add better comments to inline-styles.
* Tweaks to readme.
* Minor revisions.
- Improve the Critical / Penthouse section
- Readme corrections
- Add contributing guide
- Readme revisions
- Add mention of criticalCSS module.
- More edits
- Infra revisions
- Add note about unit tests.
- Add better comments to inline-styles.
- Tweaks to readme.
- Minor revisions.
v0.1.4 / 2014-07-11
===================
# v0.1.4 / 2014-07-11
* Add note about sample project
* Strap update
* improve tests
* Tweak to readme.
* Update README.md
* fix all the things
* Attempt to fix builds
* README.md: break long lines.
* Lint fixes.
* Whitespace normalization
* package.json: Add missing properties.
- Add note about sample project
- Strap update
- improve tests
- Tweak to readme.
- Update README.md
- fix all the things
- Attempt to fix builds
- README.md: break long lines.
- Lint fixes.
- Whitespace normalization
- package.json: Add missing properties.
v0.1.3 / 2014-07-04
===================
# v0.1.3 / 2014-07-04
* Add support for generateInline
- Add support for generateInline
v0.1.2 / 2014-07-04
===================
# v0.1.2 / 2014-07-04
* Address path issues post-integration testing
- Address path issues post-integration testing
v0.1.1 / 2014-07-04
===================
# v0.1.1 / 2014-07-04
* Add missing file to package
* Update to latest Oust, API
* Add syntax highlighting to code blocks
- Add missing file to package
- Update to latest Oust, API
- Add syntax highlighting to code blocks
v0.1.0 / 2014-06-30
===================
# v0.1.0 / 2014-06-30
* Consistency of example order
* Add minification for inline styles
* Fix some style, cb issues
* Revisions for minification
* Add support for minification
* Add options to readme
* Fixes #9 - adds defaults for w/h
* Add note about FAQs, license
* Expand on joined paths
* Move reads
* Improve test descriptions
* Improve callbacks, add more tests
* Fixes #2, passes errors
* Path joins for #6, test > fixture for #10, other fixes
* Fixes #4 - drop log statements
* Fixes #5 - switch to readFile/writeFile only
* Fixes #7 - throw if src/base not specified
* Should fix #1 - only write to disk if dest specified
* Switch to integers
* Readme revisions
- Consistency of example order
- Add minification for inline styles
- Fix some style, cb issues
- Revisions for minification
- Add support for minification
- Add options to readme
- Fixes #9 - adds defaults for w/h
- Add note about FAQs, license
- Expand on joined paths
- Move reads
- Improve test descriptions
- Improve callbacks, add more tests
- Fixes #2, passes errors
- Path joins for #6, test > fixture for #10, other fixes
- Fixes #4 - drop log statements
- Fixes #5 - switch to readFile/writeFile only
- Fixes #7 - throw if src/base not specified
- Should fix #1 - only write to disk if dest specified
- Switch to integers
- Readme revisions
v0.0.1 / 2014-06-28
===================
# v0.0.1 / 2014-06-28
* API revisions, readme updates, cleanup
* Various fixes
* Add implementation.
* Add tests.
* Add testing rig.
* Add README.
* Initial package.
* Ignore.
* Initial commit
- API revisions, readme updates, cleanup
- Various fixes
- Add implementation.
- Add tests.
- Add testing rig.
- Add README.
- Initial package.
- Ignore.
- Initial commit
#!/usr/bin/env node
'use strict';
const os = require('os');
const path = require('path');
const chalk = require('chalk');

@@ -10,10 +9,6 @@ const meow = require('meow');

const stdin = require('get-stdin');
const assign = require('lodash/assign');
const reduce = require('lodash/reduce');
const isString = require('lodash/isString');
const isRegExp = require('lodash/isRegExp');
const map = require('lodash/map');
const isObject = require('lodash/isObject');
const escapeRegExp = require('lodash/escapeRegExp');
const file = require('./lib/file-helper');
const critical = require('.');

@@ -33,66 +28,56 @@

-e, --extract Extract inlined styles from referenced stylesheets
-p, --pathPrefix Path to prepend CSS assets with (defaults to /)
-f, --folder HTML Subfolder (default: '')
--ii, --inlineImages Inline images
--ua, --userAgent User agent to use when fetching remote src
--inlineImages Inline images
--ignore RegExp, @type or selector to ignore
--ignore-[OPTION] Pass options to postcss-discard. See https://goo.gl/HGo5YV
--include RegExp, @type or selector to include
--maxFileSize Sets a max file size (in bytes) for base64 inlined images
--include-[OPTION] Pass options to inline-critical. See https://goo.gl/w6SHJM
--assetPaths Directories/Urls where the inliner should start looking for assets.
--timeout Sets the maximum timeout (in milliseconds) for the operation (defaults to 30000 ms).'
--user RFC2617 basic authorization user
--pass RFC2617 basic authorization password
--penthouse-[OPTION] Pass options to penthouse. See https://goo.gl/PQ5HLL
--ua, --userAgent User agent to use when fetching remote src
`;
const minimistOpts = {
flags: {
base: {
type: 'string',
alias: 'b'
},
css: {
type: 'string',
alias: 'c'
},
width: {
alias: 'w'
},
height: {
alias: 'h'
},
folder: {
type: 'string',
alias: 'f'
},
inline: {
type: 'boolean',
alias: 'i'
},
ignore: {
type: 'string',
alias: 'I'
},
extract: {
type: 'boolean',
alias: 'e'
},
pathPrefix: {
type: 'string',
alias: 'p'
},
inlineImages: {
type: 'boolean',
alias: 'ii'
},
user: {
type: 'string'
},
pass: {
type: 'string'
},
userAgent: {
type: 'string',
alias: 'ua'
}
}
flags: {
base: {
type: 'string',
alias: 'b',
},
css: {
type: 'string',
alias: 'c',
},
width: {
alias: 'w',
},
height: {
alias: 'h',
},
inline: {
type: 'boolean',
alias: 'i',
},
extract: {
type: 'boolean',
alias: 'e',
},
inlineImages: {
type: 'boolean',
},
ignore: {
type: 'string',
},
user: {
type: 'string',
},
pass: {
type: 'string',
},
userAgent: {
type: 'string',
alias: 'ua',
},
},
};

@@ -102,103 +87,127 @@

const groupKeys = ['ignore', 'inline', 'penthouse', 'target'];
// Group args for inline-critical and penthouse
cli.flags = Object.assign({}, cli.flags, groupArgs(['inline', 'penthouse'], {
delimiter: '-'
}, minimistOpts));
const grouped = {
...cli.flags,
...groupArgs(
groupKeys,
{
delimiter: '-',
},
minimistOpts
),
};
// Cleanup cli flags and assert cammelcase keeps camelcase
cli.flags = reduce(cli.flags, (res, val, key) => {
if (key.length <= 1) {
return res;
}
/**
* Check if key is an alias
* @param {string} key Key to check
* @returns {boolean} True for alias
*/
const isAlias = key => {
if (isString(key) && key.length > 1) {
return false;
}
switch (key) {
case 'pathprefix':
res.pathPrefix = val;
break;
case 'inlineimages':
res.inlineImages = val;
break;
case 'userAgent':
res.userAgent = val;
break;
case 'maxfilesize':
res.maxFileSize = val;
break;
case 'timeout':
res.timeout = val;
break;
case 'assetpaths':
case 'assetPaths':
if (isString(val)) {
val = [val];
}
res.assetPaths = val;
break;
case 'include':
case 'ignore':
if (isString(val) || isRegExp(val)) {
val = [val];
}
res[key] = map(val || [], entry => {
// Check regex
const match = entry.match(/^\/(.*)\/([igmy]+)?$/);
const aliases = Object.keys(minimistOpts.flags)
.filter(k => minimistOpts.flags[k].alias)
.map(k => minimistOpts.flags[k].alias);
if (match) {
return new RegExp(escapeRegExp(match[1]), match[2]);
}
return entry;
});
break;
default:
res[key] = val;
break;
return aliases.includes(key);
};
/**
* Check if value is an empty object
* @param {mixed} val Value to check
* @returns {boolean} Wether or not this is an empty object
*/
const isEmptyObj = val => isObject(val) && Object.keys(val).length === 0;
/**
* Check if value is transformed to {default: val}
* @param {mixed} val Value to check
* @returns {boolean} True if it's been converted to {default: value}
*/
const isGroupArgsDefault = val => isObject(val) && Object.keys(val).length === 1 && val.default;
/**
* Return regex if value is a string like this: '/.../g'
* @param {mixed} val Value to process
* @returns {mixed} Mapped values
*/
const mapRegExpStr = val => {
if (isString(val)) {
const match = val.match(/^\/(.*)\/([igmy]+)?$/);
return (match && new RegExp(escapeRegExp(match[1]), match[2])) || val;
}
if (Array.isArray(val)) {
return val.map(v => mapRegExpStr(v));
}
return val;
};
const normalizedFlags = reduce(
grouped,
(res, val, key) => {
// Cleanup groupArgs mess ;)
if (groupKeys.includes(key)) {
// An empty object means param without value, just true
if (isEmptyObj(val)) {
val = true;
} else if (isGroupArgsDefault(val)) {
val = val.default;
}
}
if (!isAlias(key)) {
res[key] = mapRegExpStr(val);
}
return res;
}, {});
},
{}
);
function error(err) {
process.stderr.write(indentString((chalk.red('Error: ') + err.message || err), 3));
process.stderr.write(os.EOL);
process.stderr.write(indentString(help, 3));
process.exit(1);
function showError(err) {
process.stderr.write(indentString(chalk.red('Error: ') + err.message || err, 3));
process.stderr.write(os.EOL);
process.stderr.write(indentString(help, 3));
process.exit(1);
}
function run(data) {
const opts = assign({base: process.cwd()}, cli.flags);
ok = true;
const {_: inputs, ...opts} = {...normalizedFlags};
const [input] = inputs || [];
ok = true;
if (data) {
opts.html = data;
} else {
opts.src = cli.input[0]; // eslint-disable-line prefer-destructuring
if (opts.src && !file.isExternal(opts.src)) {
opts.src = path.resolve(cli.input[0]);
}
}
if (data) {
opts.html = data;
} else {
opts.src = input;
}
try {
critical.generate(opts, (err, val) => {
if (err) {
error(err);
} else {
process.stdout.write(val, process.exit);
}
});
} catch (err) {
error(err);
}
try {
critical.generate(opts, (error, val) => {
if (error) {
showError(error);
} else {
process.stdout.write(val.css, process.exit);
}
});
} catch (error) {
showError(error);
}
}
if (cli.input[0]) {
run();
} else {
// Get stdin
stdin().then(run); /* eslint-disable-line promise/prefer-await-to-then */
setTimeout(() => {
if (ok) {
return;
}
run();
} else {
// Get stdin
stdin().then(run);
setTimeout(() => {
if (ok) {
return;
}
run();
}, 100);
}, 100);
}

@@ -1,183 +0,91 @@

'use strict';
/* eslint promise/prefer-await-to-then:0 */
const path = require('path');
const fs = require('fs-extra');
const assign = require('lodash/assign');
const defaults = require('lodash/defaults');
const isFunction = require('lodash/isFunction');
const isObject = require('lodash/isObject');
const intersection = require('lodash/intersection');
const keys = require('lodash/keys');
const chalk = require('chalk');
const sourceInliner = require('inline-critical');
const Bluebird = require('bluebird');
const through2 = require('through2');
const PluginError = require('plugin-error');
const replaceExtension = require('replace-ext');
const {create} = require('./src/core');
const {getOptions} = require('./src/config');
//
// process.on('unhandledRejection', reason => {
// console.log('Unhandled Rejection at:', reason.stack || reason);
// });
const {cleanup} = require('./lib/gc');
const core = require('./lib/core');
const file = require('./lib/file-helper');
/**
* Normalize options
*
* @param opts
*/
function prepareOptions(opts) {
if (!opts) {
opts = {};
}
const options = defaults(opts, {
base: file.guessBasePath(opts),
dimensions: [{
height: opts.height || 900,
width: opts.width || 1300
}]
});
// Set dest relative to base if isn't specivied absolute
if (options.dest && !path.isAbsolute(options.dest)) {
options.dest = path.join(options.base, options.dest);
}
// Set dest relative to base if isn't specivied absolute
if (options.destFolder && !path.isAbsolute(options.destFolder)) {
options.destFolder = path.join(options.base, options.destFolder);
}
if (!options.inline && options.extract) {
console.error(chalk.red('The extract option requires inline:true'));
}
// Set options for inline-critical
options.inline = Boolean(options.inline) && assign({
minify: opts.minify || false,
extract: opts.extract || false,
basePath: opts.base || process.cwd()
}, (isObject(options.inline) && options.inline) || {});
// Set penthouse options
options.penthouse = assign({}, {
forceInclude: opts.include || [],
timeout: opts.timeout || 30000,
maxEmbeddedBase64Length: opts.maxImageFileSize || 10240
}, options.penthouse || {});
// Show overwrite warning if penthouse params url, css, witdh or height are present
const checkOpts = intersection(keys(options.penthouse), ['url', 'css', 'width', 'height']);
if (checkOpts.length > 0) {
console.warn(chalk.yellow('Detected presence of penthouse options:'), checkOpts.join(', '));
console.warn(chalk.yellow('These options will be overwritten by critical during the process.'));
}
return options;
}
/**
* Critical path CSS generation
* @param {object} opts Options
* @param {object} params Options
* @param {function} cb Callback
* @accepts src, base, width, height, dimensions, dest
* @return {Promise}|undefined
* @return {Promise<object>} Result object with html, css & optional extracted original css
*/
exports.generate = function (opts, cb) {
opts = prepareOptions(opts);
async function generate(params, cb) {
try {
const options = getOptions(params);
const {target = {}} = options;
const {css, html} = await create(options);
// Generate critical css
let corePromise = core.generate(opts);
// Store generated css
if (opts.styleTarget) {
corePromise = corePromise.then(output => fs.outputFile(path.resolve(opts.styleTarget), output).then(() => output));
if (target.css) {
await fs.outputFile(path.resolve(target.css), css);
}
// Inline
if (opts.inline) {
corePromise = Promise.all([file.getVinylPromise(opts), corePromise])
.then(([file, css]) => {
if (css) {
return sourceInliner(file.contents.toString(), css, opts.inline);
}
return file.contents.toString();
});
// Store generated html
if (target.html) {
await fs.outputFile(path.resolve(target.html), html);
}
// Save to file
if (opts.dest) {
corePromise = corePromise.then(output => fs.outputFile(path.resolve(opts.dest), output).then(() => output));
if (typeof cb === 'function') {
cb(null, {css, html});
return;
}
// Return promise if callback is not defined
if (isFunction(cb)) {
corePromise.catch(err => { // eslint-disable-line promise/valid-params
cleanup();
cb(err);
throw new Bluebird.CancellationError();
}).then(output => {
cleanup();
cb(null, output.toString());
}).catch(Bluebird.CancellationError, () => {
console.log('Canceled due to an error');
/* Everything already done */
});
} else {
return corePromise.then(output => {
cleanup();
return output;
});
return {css, html};
} catch (error) {
if (typeof cb === 'function') {
cb(error);
return;
}
};
/**
* Deprecated has been removed
*/
exports.generateInline = function () {
throw new Error('"generateInline" has been removed. Use "generate" with the inline option instead. https://goo.gl/7VbE4b');
};
throw error;
}
}
/**
* Deprecated has been removed
*/
exports.inline = function () {
throw new Error('"inline" has been removed. Consider using "inline-critical" instead. https://goo.gl/MmTrUZ');
};
/**
* Streams wrapper for critical
*
* @param {object} opts
* @returns {*}
* @param {object} params Critical options
* @returns {stream} Gulp stream
*/
exports.stream = function (opts) {
// Return stream
return through2.obj(function (file, enc, cb) {
if (file.isNull()) {
return cb(null, file);
}
function stream(params) {
// Return stream
return through2.obj(function(file, enc, cb) {
if (file.isNull()) {
return cb(null, file);
}
if (file.isStream()) {
return this.emit('error', new PluginError('critical', 'Streaming not supported'));
if (file.isStream()) {
return this.emit('error', new PluginError('critical', 'Streaming not supported'));
}
Promise.resolve()
.then(() => generate({...params, src: file}))
.then(({css, html}) => {
// Rename file if not inlined
if (params.inline) {
file.contents = Buffer.from(html);
} else {
file.path = replaceExtension(file.path, '.css');
file.contents = Buffer.from(css);
}
const options = assign(opts || {}, {
src: file
});
cb(null, file);
})
.catch(error => cb(new PluginError('critical', error.message)));
});
}
exports.generate(options, (err, data) => {
if (err) {
return cb(new PluginError('critical', err.message));
}
generate.stream = stream;
// Rename file if not inlined
if (!opts.inline) {
file.path = replaceExtension(file.path, '.css');
}
file.contents = Buffer.from(data);
cb(err, file);
});
});
module.exports = {
generate,
stream,
};
{
"name": "critical",
"version": "1.3.4",
"version": "2.0.0-0",
"description": "Extract & Inline Critical-path CSS from HTML",

@@ -9,3 +9,4 @@ "author": "Addy Osmani",

"scripts": {
"test": "xo && mocha test/*.js --timeout 100000"
"test": "xo && jest --coverage",
"coveralls": "cat ./coverage/lcov.info | coveralls"
},

@@ -15,3 +16,3 @@ "files": [

"index.js",
"lib"
"src"
],

@@ -26,26 +27,33 @@ "bin": "cli.js",

"engines": {
"node": ">=6.4.0"
"node": ">=8"
},
"dependencies": {
"async-exit-hook": "^2.0.1",
"bluebird": "^3.5.1",
"chalk": "^2.3.0",
"clean-css": "^4.1.9",
"debug": "3.1.0",
"filter-css": "^0.1.2",
"clean-css": "^4.2.1",
"common-tags": "^1.8.0",
"css-url-parser": "^1.1.3",
"debug": "^4.1.0",
"delay": "^4.1.0",
"find-up": "^3.0.0",
"fs-extra": "^7.0.0",
"get-port": "^3.2.0",
"get-port": "^4.0.0",
"get-stdin": "^6.0.0",
"got": "^8.3.2",
"globby": "^8.0.1",
"got": "^9.2.2",
"group-args": "^0.1.0",
"indent-string": "^3.2.0",
"inline-critical": "^4.0.4",
"lodash": "^4.17.5",
"inline-critical": "^4.0.5",
"is-glob": "^4.0.0",
"joi": "^14.0.1",
"lodash": "^4.17.11",
"meow": "^5.0.0",
"mime-types": "^2.1.19",
"oust": "^0.4.0",
"penthouse": "^1.6.2",
"p-all": "^1.0.0",
"penthouse": "^1.10.1",
"plugin-error": "^1.0.1",
"postcss": "^7.0.0",
"postcss": "^7.0.5",
"postcss-discard": "^0.1.1",
"postcss-image-inliner": "^2.0.0",
"postcss-url": "^8.0.0",
"prettier": "^1.14.3",
"replace-ext": "^1.0.0",

@@ -59,9 +67,13 @@ "slash": "^2.0.0",

"async": "^2.6.1",
"chai": "^4.1.2",
"chai": "^4.2.0",
"coveralls": "^3.0.2",
"eslint-plugin-prettier": "^3.0.0",
"execa": "^0.9.0",
"finalhandler": "^1.1.0",
"jest": "^23.6.0",
"mocha": "5.2.0",
"mockery": "^2.1.0",
"normalize-newline": "^3.0.0",
"nsp": "^3.1.0",
"read-package-json": "^2.0.12",
"read-pkg-up": "^4.0.0",
"serve-static": "^1.13.1",

@@ -71,10 +83,24 @@ "stream-array": "^1.1.2",

"vinyl-source-stream": "^2.0.0",
"xo": "0.21.1"
"xo": "^0.23.0"
},
"xo": {
"space": 4,
"rules": {
"valid-jsdoc": "off"
}
"space": 2,
"prettier": true,
"ignores": [
"test",
"lib"
],
"rules": {}
},
"prettier": {
"trailingComma": "es5",
"singleQuote": true,
"printWidth": 120,
"bracketSpacing": false
},
"jest": {
"roots": [
""
]
}
}

@@ -1,6 +0,6 @@

# critical [![NPM version][npm-image]][npm-url] [![Linux Build Status][travis-image]][travis-url] [![Windows Build status][appveyor-image]][appveyor-url] [![dependencies Status][depstat-image]][depstat-url] [![devDependencies Status Status][devdepstat-image]][devdepstat-url]
# critical [![NPM version][npm-image]][npm-url] [![Linux Build Status][travis-image]][travis-url] [![Windows Build status][appveyor-image]][appveyor-url] [![dependencies Status][depstat-image]][depstat-url] [![devDependencies Status][devdepstat-image]][devdepstat-url] [![Coverage][coveralls-image]][coveralls-url]
Critical extracts & inlines critical-path (above-the-fold) CSS from HTML
![](https://i.imgur.com/lAzmBD2.png)
![Preview](https://i.imgur.com/lAzmBD2.png)

@@ -10,6 +10,17 @@

#### Install upcomming version
```sh
$ npm i -D critical@next
```
$ npm install --save critical
#### Install latest stable version
```sh
$ npm i -D critical@latest
```
The docs for the latest version can be found [here](https://github.com/addyosmani/critical/tree/v1.3.4).
## Breaking Changes
We’ve introduced some breaking changes in this release so be sure to check out the [changelog](./CHANGELOG.md).
## Build plugins

@@ -63,5 +74,4 @@

// Target for final HTML output.
// use some CSS file when the inline option is not set
dest: 'index-critical.html',
// Output results to file
target: {css: 'critical.css', html: 'index-critical.html'},

@@ -77,10 +87,8 @@ // Minify critical-path CSS when inlining

// Prefix for asset directory
pathPrefix: '/MySubfolderDocrot',
// ignore CSS rules
ignore: ['font-face',/some-regexp/],
// overwrite default options
ignoreOptions: {}
ignore: {
atrule: ['@font-face'],
rule: [/some-regexp/],
decl: (node, value) => /big-image\.png/.test(value)
}
});

@@ -98,3 +106,3 @@ ```

src: 'index.html',
dest: 'index-critical.html',
target: 'index-critical.html',
width: 1300,

@@ -113,3 +121,3 @@ height: 900

src: 'index.html',
dest: 'styles/main.css',
target: 'styles/main.css',
width: 1300,

@@ -126,4 +134,3 @@ height: 900

src: 'index.html',
dest: 'styles/styles.min.css',
minify: true,
target: 'styles/styles.min.css',
width: 1300,

@@ -141,4 +148,3 @@ height: 900

src: 'index.html',
dest: 'index-critical.html',
minify: true,
target: {html: 'index-critical.html', css: 'critical.css'}
width: 1300,

@@ -156,6 +162,7 @@ height: 900

width: 1300,
height: 900
}, function (err, output) {
// You now have critical-path CSS
// Works with and without dest specified
height: 900,
inline: true
}, function (err, ({css, html})) {
// You now have critical-path CSS as well as the modified html
// Works with and without target specified
...

@@ -173,4 +180,4 @@ });

height: 900
}).then(function (output) {
// You now have critical-path CSS
}).then(function (({css, html})) {
// You now have critical-path CSS as well as the modified html
// Works with and without dest specified

@@ -183,2 +190,13 @@ ...

Generate and return output via async function:
```js
const {css} = await critical.generate({
base: 'test/',
src: 'index.html',
width: 1300,
height: 900
});
```
### Generate critical-path CSS with multiple resolutions

@@ -213,7 +231,30 @@

dest: 'styles/main.css',
ignore: ['@font-face',/url\(/]
ignore: {
atrule: ['@font-face'],
decl: (node, value) => /url\(/.test(value)
}
});
```
### Generate critical-path CSS and specify asset rebase behaviour
```js
critical.generate({
base: 'test/',
src: 'index.html',
dest: 'styles/main.css',
rebase: {from: '/styles/main.css', to: '/folder/subfolder/index.html'}
});
```
```js
critical.generate({
base: 'test/',
src: 'index.html',
dest: 'styles/main.css',
rebase: asset => `https://my-cdn.com${asset.absolutePath}`
});
```
### Options

@@ -226,12 +267,9 @@

| html | `string` | | HTML source to be operated against. This option takes precedence over the `src` option. |
| folder           | `string`           | | HTML source folder. Required to compute relative asset paths in conjunction with the `html` option |
| css | `array` | `[]` | An array of paths to css files, or an array of [Vinyl](https://www.npmjs.com/package/vinyl) file objects.
| css | `array` | `[]` | An array of paths to css files, file globs or [Vinyl](https://www.npmjs.com/package/vinyl) file objects.
| src | `string` | | Location of the HTML source to be operated against |
| dest | `string` | | Location of where to save the output of an operation (will be relative to base if no absolute path is set) |
| destFolder | `string` | `''` | Subfolder relative to base directory. Only relevant without src (if raw html is provided) or if the destination is outside base |
| styleTarget | `string` | | Target file to store the generated critical-path styles |
| target | `string`|`object` | | Location of where to save the output of an operation. Use an object with 'html' and 'css' props if you want to store both |
| width | `integer` | `900` | Width of the target viewport |
| height | `integer` | `1300` | Height of the target viewport |
| dimensions | `array` | `[]` | An array of objects containing height and width. Takes precedence over `width` and `height` if set
| minify | `boolean` | `false` | Enable minification of generated critical-path CSS |
| minify | `boolean` | `true` | Enable minification of generated critical-path CSS |
| extract | `boolean` | `false` | Remove the inlined styles from any stylesheets referenced in the HTML. It generates new references based on extracted content so it's safe to use for multiple HTML files referencing the same stylesheet. Use with caution. Removing the critical CSS per page results in a unique async loaded CSS file for every page. Meaning you can't rely on cache across multiple pages |

@@ -241,7 +279,4 @@ | inlineImages | `boolean` | `false` | Inline images

| maxImageFileSize | `integer` | `10240`| Sets a max file size (in bytes) for base64 inlined images
| timeout | `integer` | `30000`| Sets a maximum timeout for the operation
| pathPrefix | `string` | `/` | Path to prepend CSS assets with. You *must* make this path absolute if you are going to be using critical in multiple target files in disparate directory depths. (eg. targeting both `/index.html` and `/admin/index.html` would require this path to start with `/` or it wouldn't work.)
| include | `array` | `[]` | Force include CSS rules. See [`penthouse#usage`](https://github.com/pocketjoso/penthouse#usage-1).
| ignore | `array` | `[]` | Ignore CSS rules. See [`filter-css`](https://github.com/bezoerb/filter-css) for usage examples.
| ignoreOptions | `object` | `{}` | Ignore options. See [`filter-css#options`](https://github.com/bezoerb/filter-css#options).
| rebase | `object`|`function`| `undefined` | Critical tries it's best to rebase the asset paths relative to the document. If this doesn't work as expected you can always use this option to control the rebase paths. See [`postcss-url`](https://github.com/postcss/postcss-url) for details. (https://github.com/pocketjoso/penthouse#usage-1).
| ignore | `array`|`object` | `undefined` | Ignore CSS rules. See [`postcss-discard`](https://github.com/bezoerb/postcss-discard) for usage examples. If you pass an array all rules will be applied to atrules, rules and declarations;
| userAgent | `string` | `''` | User agent to use when fetching a remote src

@@ -255,3 +290,3 @@ | penthouse | `object` | `{}` | Configuration options for [`penthouse`](https://github.com/pocketjoso/penthouse).

```
```sh
$ npm install -g critical

@@ -262,3 +297,3 @@ ```

```
```sh
$ cat test/fixture/index.html | critical --base test/fixture --inline > index.critical.html

@@ -269,3 +304,3 @@ ```

```
```sh
$ critical test/fixture/index.html --base test/fixture > critical.css

@@ -375,1 +410,4 @@ ```

[devdepstat-image]: https://david-dm.org/addyosmani/critical/dev-status.svg
[coveralls-url]: https://coveralls.io/github/addyosmani/critical?branch=master
[coveralls-image]: https://coveralls.io/repos/github/addyosmani/critical/badge.svg?branch=master
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc