Skip to content

Commit

Permalink
adds option to customize cleanCSS output
Browse files Browse the repository at this point in the history
  • Loading branch information
bezoerb committed Sep 15, 2023
1 parent 6cd2bc5 commit 1a06253
Show file tree
Hide file tree
Showing 24 changed files with 134 additions and 61 deletions.
49 changes: 25 additions & 24 deletions README.md

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions src/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ const schema = Joi.object()
],
assetPaths: Joi.array().items(Joi.string()),
userAgent: Joi.string(),
cleanCSS: Joi.object().unknown(true),
})
.label('options')
.xor('html', 'src');
Expand Down
38 changes: 19 additions & 19 deletions src/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,22 +31,7 @@ function combineCss(cssArray) {
return cssArray[0].toString();
}

return new CleanCSS({
rebase: false,
level: {
1: {
all: true,
},
2: {
all: false,
removeDuplicateFontRules: true,
removeDuplicateMediaBlocks: true,
removeDuplicateRules: true,
removeEmpty: true,
mergeMedia: true,
},
},
}).minify(invokeMap(cssArray, 'toString').join(' ')).styles;
return new CleanCSS().minify(invokeMap(cssArray, 'toString').join(' ')).styles;
}

/**
Expand Down Expand Up @@ -93,9 +78,6 @@ function callPenthouse(document, options) {
* @return {Promise<object>} Object with critical css & html
*/
export async function create(options = {}) {
const cleanCSS = new CleanCSS({
rebase: false,
});
const {
base,
src,
Expand All @@ -108,6 +90,7 @@ export async function create(options = {}) {
maxImageFileSize,
postcss: postProcess = [],
strict,
cleanCSS: cleanCSSOptions,
concurrency = Number.POSITIVE_INFINITY,
assetPaths = [],
} = options;
Expand Down Expand Up @@ -178,6 +161,23 @@ export async function create(options = {}) {
}

// Minify or prettify
const cleanCSS = new CleanCSS(
cleanCSSOptions || {
level: {
1: {
all: true,
},
2: {
all: false,
removeDuplicateFontRules: true,
removeDuplicateMediaBlocks: true,
removeDuplicateRules: true,
removeEmpty: true,
mergeMedia: true,
},
},
}
);
criticalCSS = cleanCSS.minify(criticalCSS).styles;

const result = {
Expand Down
2 changes: 1 addition & 1 deletion test/blackbox.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ describe('generate (local)', () => {

test('should rewrite relative images for html outside root', (done) => {
const expected = read('expected/generate-image-relative.css');
const target = path.resolve('fixtures/folder/.image-relative.css');
const target = path.resolve('fixtures/folder/.mage-relative.css');

generate(
{
Expand Down
44 changes: 44 additions & 0 deletions test/core.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import getPort from 'get-port';
import serveStatic from 'serve-static';
import {create} from '../src/core.js';
import {read} from './helper/index.js';
import CleanCSS from 'clean-css';

Check failure on line 11 in test/core.test.js

View workflow job for this annotation

GitHub Actions / Node 14 on ubuntu-latest

`clean-css` import should occur before import of `../src/core.js`

Check failure on line 11 in test/core.test.js

View workflow job for this annotation

GitHub Actions / Node 14 on windows-latest

`clean-css` import should occur before import of `../src/core.js`

Check failure on line 11 in test/core.test.js

View workflow job for this annotation

GitHub Actions / Node 16 on ubuntu-latest

`clean-css` import should occur before import of `../src/core.js`

Check failure on line 11 in test/core.test.js

View workflow job for this annotation

GitHub Actions / Node 16 on windows-latest

`clean-css` import should occur before import of `../src/core.js`

Check failure on line 11 in test/core.test.js

View workflow job for this annotation

GitHub Actions / Node 18 on ubuntu-latest

`clean-css` import should occur before import of `../src/core.js`

Check failure on line 11 in test/core.test.js

View workflow job for this annotation

GitHub Actions / Node 18 on windows-latest

`clean-css` import should occur before import of `../src/core.js`

Check failure on line 11 in test/core.test.js

View workflow job for this annotation

GitHub Actions / Node 14 on ubuntu-latest

`clean-css` import should occur before import of `../src/core.js`

Check failure on line 11 in test/core.test.js

View workflow job for this annotation

GitHub Actions / Node 14 on windows-latest

`clean-css` import should occur before import of `../src/core.js`

Check failure on line 11 in test/core.test.js

View workflow job for this annotation

GitHub Actions / Node 16 on ubuntu-latest

`clean-css` import should occur before import of `../src/core.js`

Check failure on line 11 in test/core.test.js

View workflow job for this annotation

GitHub Actions / Node 16 on windows-latest

`clean-css` import should occur before import of `../src/core.js`

Check failure on line 11 in test/core.test.js

View workflow job for this annotation

GitHub Actions / Node 18 on ubuntu-latest

`clean-css` import should occur before import of `../src/core.js`

Check failure on line 11 in test/core.test.js

View workflow job for this annotation

GitHub Actions / Node 18 on windows-latest

`clean-css` import should occur before import of `../src/core.js`

const __dirname = fileURLToPath(new URL('.', import.meta.url));
jest.setTimeout(100_000);
Expand Down Expand Up @@ -45,9 +46,52 @@ test('Generate critical-path CSS', async () => {
const result = await create({
src: `http://localhost:${port}/generate-default.html`,
});

expect(result.css).toBe(css);
expect(result.html).toBe(html);
} catch (error) {
expect(error).toBe(undefined);
}
});

test('Generate critical-path CSS with custom cleancss config', async () => {
const css = read('fixtures/styles/issue-562.css');
const html = read('fixtures/issue-562.html');

const optionsArray = [
{
level: 2,
format: 'beautify',
},
{
level: 1,
},
];

for (const options of optionsArray) {
const expected = new CleanCSS(options).minify(css).styles;

try {
const result = await create({

Check failure on line 75 in test/core.test.js

View workflow job for this annotation

GitHub Actions / Node 14 on ubuntu-latest

Unexpected `await` inside a loop.

Check failure on line 75 in test/core.test.js

View workflow job for this annotation

GitHub Actions / Node 14 on windows-latest

Unexpected `await` inside a loop.

Check failure on line 75 in test/core.test.js

View workflow job for this annotation

GitHub Actions / Node 16 on ubuntu-latest

Unexpected `await` inside a loop.

Check failure on line 75 in test/core.test.js

View workflow job for this annotation

GitHub Actions / Node 16 on windows-latest

Unexpected `await` inside a loop.

Check failure on line 75 in test/core.test.js

View workflow job for this annotation

GitHub Actions / Node 18 on ubuntu-latest

Unexpected `await` inside a loop.

Check failure on line 75 in test/core.test.js

View workflow job for this annotation

GitHub Actions / Node 18 on windows-latest

Unexpected `await` inside a loop.

Check failure on line 75 in test/core.test.js

View workflow job for this annotation

GitHub Actions / Node 14 on ubuntu-latest

Unexpected `await` inside a loop.

Check failure on line 75 in test/core.test.js

View workflow job for this annotation

GitHub Actions / Node 14 on windows-latest

Unexpected `await` inside a loop.

Check failure on line 75 in test/core.test.js

View workflow job for this annotation

GitHub Actions / Node 16 on ubuntu-latest

Unexpected `await` inside a loop.

Check failure on line 75 in test/core.test.js

View workflow job for this annotation

GitHub Actions / Node 16 on windows-latest

Unexpected `await` inside a loop.

Check failure on line 75 in test/core.test.js

View workflow job for this annotation

GitHub Actions / Node 18 on ubuntu-latest

Unexpected `await` inside a loop.

Check failure on line 75 in test/core.test.js

View workflow job for this annotation

GitHub Actions / Node 18 on windows-latest

Unexpected `await` inside a loop.
src: `http://localhost:${port}/issue-562.html`,
cleanCSS: options,
inline: false,
dimensions: [
{
width: 100,
height: 70,
},
{
width: 1000,
height: 70,
},
],
});

expect(result.css).toBe(expected);
expect(result.html).toBe(html);
} catch (error) {
expect(error).toBe(undefined);
}
}
});
2 changes: 1 addition & 1 deletion test/expected/generate-default-nostyle.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion test/expected/generate-default-nostyle.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Place favicon.ico and apple-touch-icon.png in the root directory -->

<style>html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a{background:0 0}h1{margin:.67em 0;font-size:2em}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:62.5%}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}a{color:#428bca;text-decoration:none}h1,h3,h4{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}h1,h3{margin-top:20px;margin-bottom:10px}h4{margin-top:10px;margin-bottom:10px}h1{font-size:36px}h3{font-size:24px}h4{font-size:18px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:200;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.text-muted{color:#999}ul{margin-top:0;margin-bottom:10px}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.row{margin-right:-15px;margin-left:-15px}.col-lg-6{position:relative;min-height:1px;padding-right:15px;padding-left:15px}@media (min-width:1200px){.col-lg-6{float:left}.col-lg-6{width:50%}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;background-image:none;border:1px solid transparent;border-radius:4px}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-lg{padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a{color:#fff;background-color:#428bca}.jumbotron{padding:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.container .jumbotron{border-radius:6px}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron{padding-right:60px;padding-left:60px}.jumbotron h1{font-size:63px}}.container:after,.container:before,.nav:after,.nav:before,.row:after,.row:before{display:table;content:" "}.container:after,.nav:after,.row:after{clear:both}.pull-right{float:right!important}@-ms-viewport{width:device-width}</style>
<style>html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a{background:0 0}h1{margin:.67em 0;font-size:2em}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:62.5%}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}a{color:#428bca;text-decoration:none}h1,h3,h4{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}h1,h3{margin-top:20px;margin-bottom:10px}h4{margin-top:10px;margin-bottom:10px}h1{font-size:36px}h3{font-size:24px}h4{font-size:18px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:200;line-height:1.4}.text-muted{color:#999}ul{margin-top:0;margin-bottom:10px}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.lead{font-size:21px}.container{width:750px}}@media (min-width:992px){.container{width:970px}}.row{margin-right:-15px;margin-left:-15px}.col-lg-6{position:relative;min-height:1px;padding-right:15px;padding-left:15px}@media (min-width:1200px){.container{width:1170px}.col-lg-6{float:left}.col-lg-6{width:50%}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;background-image:none;border:1px solid transparent;border-radius:4px}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-lg{padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a{color:#fff;background-color:#428bca}.jumbotron{padding:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.container .jumbotron{border-radius:6px}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron{padding-right:60px;padding-left:60px}.jumbotron h1{font-size:63px}}.container:after,.container:before,.nav:after,.nav:before,.row:after,.row:before{display:table;content:" "}.container:after,.nav:after,.row:after{clear:both}.pull-right{float:right!important}@-ms-viewport{width:device-width}</style>
</head>
<body>
<!--[if lt IE 10]>
Expand Down
Loading

0 comments on commit 1a06253

Please sign in to comment.