Skip to content

Commit

Permalink
chore: removed yarn in favor of npm
Browse files Browse the repository at this point in the history
chore!: changed crittr to ESM
fix: tests where also transformed and fixed
chore: added conventional commits with release-please for versioning
chore!: Minimum nodejs version is 18
chore: updated dependecies to newest versions
  • Loading branch information
philipp-winterle committed Jun 17, 2024
1 parent 0786481 commit b7ec137
Show file tree
Hide file tree
Showing 30 changed files with 12,532 additions and 3,647 deletions.
7 changes: 4 additions & 3 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"ecmaVersion": 12,
"sourceType": "script"
},
"plugins": ["@babel"],
"plugins": ["@babel", "sort-destructure-keys"],
"rules": {
"accessor-pairs": "error",
"array-bracket-newline": "error",
Expand Down Expand Up @@ -225,7 +225,6 @@
"semi-spacing": "error",
"semi-style": "error",
"sort-imports": "off",
"sort-keys": "error",
"sort-vars": "error",
"space-before-blocks": "error",
"space-before-function-paren": "off",
Expand All @@ -244,6 +243,8 @@
"wrap-iife": "error",
"wrap-regex": "error",
"yield-star-spacing": "error",
"yoda": "error"
"yoda": "error",
"sort-keys": ["error", "asc", { "caseSensitive": true, "natural": true, "minKeys": 5 }],
"sort-destructure-keys/sort-destructure-keys": ["warn", { "caseSensitive": true }]
}
}
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ tmp/*
yarn-error.log
test.js
.vscode
test/screenshots
test/results/*
!test/results/.gitkeep
test/*.css
2 changes: 0 additions & 2 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

npm test
42 changes: 21 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@
#### Feature Facts

- Amazing speed
- Designed to be used by power users as a nodejs module (no useless browser usage)
- :boom: **Only library which is able to extract summarized critical css from multiple urls which has a common use case -> Most of the websites using one css file for multiple subpages** :boom: :metal:
- When using multiple urls a max concurrency of extraction is adjustable. For machines with less power
- Ongoing maintenance because of being used in enterprise environment
- Returns not only the critical css. Also returns the remaining css of your given file. You don't need to include the full css on your page or reduce the css on your own :heart:
- Amazing speed
- Designed to be used by power users as a nodejs module (no useless browser usage)
- :boom: **Only library which is able to extract summarized critical css from multiple urls which has a common use case -> Most of the websites using one css file for multiple subpages** :boom: :metal:
- When using multiple urls a max concurrency of extraction is adjustable. For machines with less power
- Ongoing maintenance because of being used in enterprise environment
- Returns not only the critical css. Also returns the remaining css of your given file. You don't need to include the full css on your page or reduce the css on your own :heart:

## Performance

Expand All @@ -33,10 +33,10 @@ There are some other libraries out there dealing with the topic of extracting th

### Requirements

- minimum nodejs > 12 | recommended nodejs 16+
- async/await
- Promises
- puppeteer dependecies on UNIX bases OS (including MacOSX)
- minimum nodejs > 12 | recommended nodejs 16+
- async/await
- Promises
- puppeteer dependecies on UNIX bases OS (including MacOSX)

> Due to some dependencies of crittr you may need to install some additional software.
> Puppeteer has some special requirements if you are running on an UNIX based operation system. You can read more about this fact here. Including a list of what to install: [Puppeteer Troubleshooting](https://github.com/GoogleChrome/puppeteer/blob/master/docs/troubleshooting.md#chrome-headless-doesnt-launch)
Expand All @@ -45,7 +45,7 @@ There are some other libraries out there dealing with the topic of extracting th

To use crittr as a module or cli in your nodejs environment just install it with

```
```shell
npm i crittr
```

Expand Down Expand Up @@ -166,7 +166,7 @@ Crittr({

You can see the output of the time measurement after every run. So you will be able to check you overall processing time.

```
```shell
▶ Crittr Run Initialized timer...
◼ Crittr Run Timer run for: 2.33s
```
Expand Down Expand Up @@ -253,20 +253,20 @@ This keepSelectors options will match every selector that begins with `.test` an

## FAQ :confused:

- Why do I need to put my css file in when I only want to extract the critical css?
- Why do I need to put my css file in when I only want to extract the critical css?
You don't need to but if you don't set your css file as an option you may not receive all vendor prefixes you may expect. This is due testing with only one browser engine which drop other prefixes.
- After including the remaining css aswell my page starts looking different. Why is that?
- After including the remaining css aswell my page starts looking different. Why is that?
If you progress more than 1 url at the same time crittr can not determinate where a rule has to be positioned in the whole css to not get in conflict with other rules overwriting them. You have to write clean css to prevent such an behaviour. Overwriting rules should always have longer selectors than the rules they are overwriting to raise priority.

## Upcoming :trumpet:

- [ ] :star: cookie includes
- [x] :star: wildcards
- [x] :+1: compress output option
- [x] :fire: return of the remaining css aswell
- [x] :grey_question: multi selector partial matches
- [x] :tea: returning of remaining css aswell (optional)
- [x] :clock2: performance boost for large css
- [ ] :star: cookie includes
- [x] :star: wildcards
- [x] :+1: compress output option
- [x] :fire: return of the remaining css aswell
- [x] :grey_question: multi selector partial matches
- [x] :tea: returning of remaining css aswell (optional)
- [x] :clock2: performance boost for large css

## Known Bugs :shit:

Expand Down
40 changes: 16 additions & 24 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,42 +1,34 @@
'use strict';
global.crittr_project_path = __dirname;

const log = require('signale');
const path = require('path');
import { createRequire } from 'node:module';
import log from '@dynamicabot/signales';
import path from 'path';
import url from 'url';
const __dirname = url.fileURLToPath(new URL('.', import.meta.url));
const NODE_ENV = process.env.NODE_ENV || 'production';

let IS_NPM_PACKAGE = false;
try {
const require = createRequire(import.meta.url);
IS_NPM_PACKAGE = !!require.resolve('crittr');
} catch (e) {}

const pathToCrittr = NODE_ENV === 'development' && !IS_NPM_PACKAGE ? 'lib' : 'lib'; // Only keep for later browser support?
const Crittr = require(path.join(__dirname, pathToCrittr, 'classes', 'Crittr.class.js'));

/**
*
* @param options
* @returns {Promise<[<string>, <string>]>}
*/
module.exports = options => {
return new Promise(async (resolve, reject) => {
log.time('Crittr Run');
export default async options => {
log.time('Crittr Run');
const { Crittr } = await import(path.join(__dirname, pathToCrittr, 'classes', 'Crittr.class.js'));

let crittr;
let resultObj = { critical: null, rest: null };

let crittr;
let resultObj = { critical: null, rest: null };
crittr = new Crittr(options);

try {
crittr = new Crittr(options);
} catch (err) {
reject(err);
}
resultObj = await crittr.run();

try {
resultObj = await crittr.run();
} catch (err) {
reject(err);
}
resolve(resultObj);
log.timeEnd('Crittr Run');
});
log.timeEnd('Crittr Run');
return resultObj;
};
9 changes: 5 additions & 4 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
// jest.config.js
module.exports = {
export default {
projects: [
{
displayName: 'Basic',
globalSetup: './test/setup.cjs',
globalTeardown: './test/teardown.cjs',
globalSetup: './test/setup.js',
globalTeardown: './test/teardown.js',
roots: ['<rootDir>'],
testMatch: ['**/test/tests/**/*.test.cjs?(x)'],
testMatch: ['**/test/tests/**/*.test.js?(x)'],
testEnvironmentOptions: {
url: 'http://localhost',
},
},
],
transform: {},
};
12 changes: 8 additions & 4 deletions lib/Constants.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
const path = require('path');
import path from 'path';
import { createRequire } from 'module';
import url from 'url';
const __dirname = url.fileURLToPath(new URL('.', import.meta.url));
const require = createRequire(import.meta.url);
const package_json = require(path.join('..', 'package.json'));

module.exports = {
export default {
// DEFAULTS
PROJECT_DIR: path.resolve('..'),
PROJECT_DIR: path.resolve(__dirname, '..'),

// CRITTR BASED

PRINT_BROWSER_CONSOLE: false,
DROP_KEYFRAMES: true,
PUPPETEER_HEADLESS: "new",
PUPPETEER_HEADLESS: 'new',
BROWSER_USER_AGENT: 'Crittr ' + package_json.version,
BROWSER_CACHE_ENABLED: true,
BROWSER_JS_ENABLED: true,
Expand Down
12 changes: 5 additions & 7 deletions lib/classes/Ast.class.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
const _ = require('lodash');
const log = require('signale');
const CONSTANTS = require('../Constants');
const Rule = require('./Rule.class');
const hash = require('object-hash');
import _ from 'lodash';
import Rule from './Rule.class.js';
import hash from 'object-hash';

// PRIVATE VARS
const REMOVEABLE_PROPS = ['position'];
Expand Down Expand Up @@ -120,7 +118,7 @@ class Ast {
break;
}

if(rulesObj[0].rule.type === 'rule' && !rulesObj[0].rule.hasOwnProperty('declarations')) {
if (rulesObj[0].rule.type === 'rule' && !rulesObj[0].rule.hasOwnProperty('declarations')) {
break;
}

Expand Down Expand Up @@ -151,4 +149,4 @@ Ast.TYPES_TO_REMOVE = ['comment'];

Ast.MEDIA_PREFIX = '@media ';

module.exports = Ast;
export default Ast;
50 changes: 24 additions & 26 deletions lib/classes/Crittr.class.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,26 @@
'use strict';

const fs = require('fs-extra');
const util = require('util');
const path = require('path');
import fs from 'fs-extra';
import util from 'util';
import path from 'path';
import doDebug from 'debug';
import log from '@dynamicabot/signales';
import chalk from 'chalk';
import merge from 'deepmerge';
import { isPlainObject } from 'is-plain-object';
import Queue from 'run-queue';
import puppeteer from 'puppeteer-extra';
import StealthPlugin from 'puppeteer-extra-plugin-stealth';
import CleanCSS from 'clean-css';
import postcss from 'postcss';
import sortMediaQueries from 'postcss-sort-media-queries';
import DEFAULTS from '../Constants.js';
import Ast from './Ast.class.js';
import CssTransformator from './CssTransformator.class.js';
import extractCriticalCss_script from '../evaluation/extract_critical_with_css.js';

const debug = doDebug('crittr:Crittr.class');
const readFilePromise = util.promisify(fs.readFile);
const debug = require('debug')('Crittr Class');
const log = require('signale');
const chalk = require('chalk');
const merge = require('deepmerge');
const { isPlainObject } = require('is-plain-object');
const Queue = require('run-queue');
const puppeteer = require('puppeteer-extra');
const StealthPlugin = require('puppeteer-extra-plugin-stealth')
puppeteer.use(StealthPlugin())
const devices = puppeteer.devices;
const CleanCSS = require('clean-css');
const postcss = require('postcss');
const sortMediaQueries = require('postcss-sort-media-queries');

const DEFAULTS = require('../Constants');
const Ast = require('./Ast.class');

const CssTransformator = require('./CssTransformator.class');
const extractCriticalCss_script = require('../evaluation/extract_critical_with_css');
puppeteer.use(StealthPlugin());

/**
* CRITTR Class
Expand Down Expand Up @@ -711,7 +709,7 @@ class Crittr {
url = url.substring(0, url.indexOf('#'));
}

const htmlContent = await fs.readFile(path.join(global.crittr_project_path, url), 'utf8');
const htmlContent = await fs.readFile(path.join(DEFAULTS.PROJECT_DIR, url), 'utf8');
await page.setContent(htmlContent);
} else {
await page.goto(url, {
Expand All @@ -730,7 +728,7 @@ class Crittr {
if (hasError === false) {
try {
debug('evaluateUrl - Extracting critical selectors');
await page.waitForTimeout(250); // Needed because puppeteer sometimes isn't able to handle quick tab openings
await new Promise(r => setTimeout(r, 250));
if (this.options.takeScreenshots === true) {
let screenName = url.replace(/[^\w\s]/gi, '_') + '.png';
if (typeof this.options.screenshotNameGenerator === 'function') {
Expand Down Expand Up @@ -807,4 +805,4 @@ class Crittr {
}
}

module.exports = Crittr;
export { Crittr, Crittr as default };
15 changes: 7 additions & 8 deletions lib/classes/CssTransformator.class.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
'use strict';
const debug = require('debug')('Crittr CSSTransformator');
const log = require('signale');
const merge = require('deepmerge');
const css = require('css');
import doDebug from 'debug';
import log from '@dynamicabot/signales';
import merge from 'deepmerge';
import css from 'css';
import Rule from './Rule.class.js';

const Rule = require('./Rule.class');
const { exists } = require('fs-extra');
const debug = doDebug('crittr:css-transformator');

/**
*
Expand Down Expand Up @@ -203,4 +202,4 @@ class CssTransformator {
}
}

module.exports = CssTransformator;
export default CssTransformator;
8 changes: 4 additions & 4 deletions lib/classes/Rule.class.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const _ = require('lodash');
const log = require('signale');
const CONSTANTS = require('../Constants');
import _ from 'lodash';
import log from '@dynamicabot/signales';
import CONSTANTS from '../Constants.js';

/**
* Rule Class with static functions to handle rule comparision and more
Expand Down Expand Up @@ -145,4 +145,4 @@ class Rule {
}
}

module.exports = Rule;
export default Rule;
4 changes: 2 additions & 2 deletions lib/evaluation/extract_critical_with_css.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { fill } = require('lodash');
import _ from 'lodash';

/**
* Used to extract critical css with the help of a source css. This will result in larger size because every vendor
Expand All @@ -9,7 +9,7 @@ const { fill } = require('lodash');
* @param keepSelectors
* @returns {Promise<Map<Object>>}
*/
module.exports = ({ sourceAst, loadTimeout, keepSelectors, removeSelectors }) => {
export default async ({ sourceAst, loadTimeout, keepSelectors, removeSelectors }) => {
return new Promise((resolve, reject) => {
// PRE CONFIG VARS
const usedSelectorTypes = ['supports', 'media', 'rule'];
Expand Down
2 changes: 1 addition & 1 deletion lib/evaluation/extract_critical_without_css.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* @param options
* @returns {*}
*/
module.exports = options => {
export default options => {
// ADJUSTMENTS
const removePseudoSelectors = !!options.removePseudoSelectors;
const keepSelectors = options.keepSelectors || [];
Expand Down
Loading

0 comments on commit b7ec137

Please sign in to comment.