Skip to content

Commit

Permalink
feat: Use @parcel/css in tinycss (#47)
Browse files Browse the repository at this point in the history
* feat: add @parcel/css

* chore: Fix test and clean up

* chore: bump parcel/css

* chore: remove postcss

* chore: replace jsdom with link dom

* chore: remove unused types

* docs: added documentattion

* chore: bump to v2.0.0
  • Loading branch information
Marabyte authored Feb 17, 2022
1 parent 731a97c commit fff9009
Show file tree
Hide file tree
Showing 10 changed files with 682 additions and 424 deletions.
965 changes: 634 additions & 331 deletions package-lock.json

Large diffs are not rendered by default.

6 changes: 2 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"reset-modules": "rm -rf **/**/node_modules"
},
"workspaces": [
"packages/*"
"./packages/*"
],
"devDependencies": {
"@changesets/changelog-github": "^0.4.2",
Expand All @@ -18,10 +18,8 @@
"@parcel/transformer-typescript-types": "^2.0.1",
"@swc/core": "^1.2.124",
"@swc/jest": "^0.2.15",
"@types/autoprefixer": "^10.2.0",
"@types/cssnano": "^4.0.0",
"@types/jest": "^26.0.14",
"@types/jsdom": "^16.2.4",
"@types/node": "^17.0.18",
"@typescript-eslint/eslint-plugin": "^4.6.1",
"@typescript-eslint/parser": "^4.6.1",
"eslint": "^7.12.1",
Expand Down
19 changes: 7 additions & 12 deletions packages/tinycss/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,9 @@ An 11ty plugin to optimise CSS.

You can pass [PurgeCSS configuration object](https://purgecss.com/plugins/postcss.html#options) in the [plugin's options](./Configuration)

- Uses [Autoprefixer](https://autoprefixer.github.io/) to add vendor specific prefixes.
- Uses [Browserslist](https://autoprefixer.github.io/) to add vendor specific prefixes.

You can pass [Autoprefixer options](https://github.com/postcss/autoprefixer#options) in the [plugin's options](./Configuration)

- Uses [CSSNano](https://cssnano.co/) to minify and optimise the final CSS.

You can config CSSNano with the default [config files](https://cssnano.co/docs/config-file/#cssnano-config-files)
You can pass a list of browsers in the [plugin's options](./Configuration) . Alternatively it will look for a `.browserslistrc` file or a `browserslist` in `package.json`. Check the details [here](https://github.com/browserslist/browserslist#config-file)

## Requirements

Expand Down Expand Up @@ -167,24 +163,23 @@ module.exports = function (eleventyConfig) {
};
```

### Autoprefixer options
### Browserslist options

You can pass your own options just like in [the official documentation](https://github.com/postcss/autoprefixer#options) :
You can pass a list of browsers as a string :

```javascript
const tinyCSS = require('@sardine/eleventy-plugin-tinycss');
module.exports = function (eleventyConfig) {
const tinyOptions = {
autoprefixer: {
// keep browser prefixes
remove: false,
},
browserslist: 'last 2 version, not dead',
};

eleventyConfig.addPlugin(tinyCSS, tinyOptions);
};
```

Alternatively it will look for a `.browserslistrc` file or a `browserslist` in `package.json`. Check the details [here](https://github.com/browserslist/browserslist#config-file)

## License

[MIT](./LICENSE)
2 changes: 1 addition & 1 deletion packages/tinycss/__tests__/tiny.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ test('should read both an external CSS file and inline CSS and then inline optim
<!DOCTYPE html>
<html>
<head>
<style>.a{font-size:large;padding:.5rem}</style>
<style>.a{font-size:large} .a{padding:.5rem}</style>
</head>
<body>
<h1 class="a">Hello!</h1>
Expand Down
14 changes: 7 additions & 7 deletions packages/tinycss/__tests__/util.test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { getExternalFiles, minify } from '../lib/util';
import { replaceWhitespace } from '../../../util/util';
import { JSDOM } from 'jsdom';
import { parseHTML } from 'linkedom';

test('should return a promise with the contents of a CSS file', async () => {
const dom = new JSDOM();
const document = dom.window.document;
const html = `<!DOCTYPE html><html></html>`;
const { document } = parseHTML(html);
const linkElement: HTMLLinkElement = document.createElement('link');
linkElement.href = '/mocks/styles.css';

Expand Down Expand Up @@ -34,18 +34,18 @@ test('should return a promise with the CSS styles used in the HTML', async () =>
return expect(optimisedCSS).toBe(expected);
});

test('should accept Autoprefixer options', async () => {
const fullCSS = `.a {font-size: large;-webkit-border-radius: 12px;border-radius: 12px;}\n`;
test('should accept Browserslist options', async () => {
const fullCSS = `.a {-webkit-border-radius:12px;font-size: large;border-radius: 12px;}\n`;
const baseHTML = `<!DOCTYPE html>
<html>
<body>
<h1 class="a">Hello!</h1>
</body>
</html>`;

const expected = `.a{-webkit-border-radius:12px;border-radius:12px;font-size:large}`;
const expected = `.a{border-radius:12px;font-size:large}`;

let optimisedCSS = await minify(fullCSS, baseHTML, { autoprefixer: { remove: false } });
let optimisedCSS = await minify(fullCSS, baseHTML, { browserslists: 'last 2 versions' });
optimisedCSS = replaceWhitespace(optimisedCSS);

return expect(optimisedCSS).toBe(expected);
Expand Down
7 changes: 3 additions & 4 deletions packages/tinycss/lib/options.interface.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import autoprefixer from 'autoprefixer';
import { PurgeCSSOptions } from './purgeCSS.interface';
import type { UserDefinedOptions as PurgeCSSOptions } from 'purgecss';

export interface OptionsInterface {
/** Autoprefixer options */
autoprefixer?: autoprefixer.Options;
/** The 11ty output directory. It defaults to `_site` */
output?: string;
/** PurgeCSS Options : https://purgecss.com/configuration.html#options */
purgeCSS?: PurgeCSSOptions;
browserslists?: string;
}
36 changes: 0 additions & 36 deletions packages/tinycss/lib/purgeCSS.interface.ts

This file was deleted.

8 changes: 4 additions & 4 deletions packages/tinycss/lib/tiny.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { JSDOM } from 'jsdom';
import { parseHTML } from 'linkedom';
import { OptionsInterface } from './options.interface';
import { getExternalFiles, minify } from './util';

Expand All @@ -10,8 +10,8 @@ import { getExternalFiles, minify } from './util';
* @param options The plugin options
*/
export const tiny = async (html: string, options?: OptionsInterface): Promise<string> => {
const dom = new JSDOM(html);
const document = dom.window.document;
const { document } = parseHTML(html);

const styles: HTMLStyleElement[] = [...document.querySelectorAll('style')];
const links: HTMLLinkElement[] = [...document.querySelectorAll<HTMLLinkElement>('link[rel=stylesheet]')];

Expand Down Expand Up @@ -48,7 +48,7 @@ export const tiny = async (html: string, options?: OptionsInterface): Promise<st
const inlinStyle = document.createTextNode(minicss);
inline.appendChild(inlinStyle);
head.appendChild(inline);
html = dom.serialize();
html = document.toString();
}

return html;
Expand Down
38 changes: 19 additions & 19 deletions packages/tinycss/lib/util.ts
Original file line number Diff line number Diff line change
@@ -1,46 +1,46 @@
import autoprefixer, { Options as AutoprefixerOptions } from 'autoprefixer';
import cssnano from 'cssnano';
import postcss, { AcceptedPlugin } from 'postcss';
import purgecss from '@fullhuman/postcss-purgecss';
import { PurgeCSS } from 'purgecss';
import type { UserDefinedOptions as PurgeCSSOptions } from 'purgecss';
import browserslist from 'browserslist';
import { transform, browserslistToTargets } from '@parcel/css';
import { promises } from 'fs';
import { OptionsInterface } from './options.interface';
import { PurgeCSSOptions } from './purgeCSS.interface';

/**
* Transforms the CSS to a production ready state.
* - PurgeCSS removes all unused CSS.
* - Autoprefixer applies vendor specific prefixes
* - CSSNano minifies the remaining CSS
* @param {string} css The page CSS content
* @param {string} rawCss The page CSS content
* @param {string} html The raw HTML content
*/
export async function minify(css: string, html: string, options?: OptionsInterface): Promise<string> {
export async function minify(rawCss: string, html: string, options?: OptionsInterface): Promise<string> {
try {
const userAutoprefixerOptions = options?.autoprefixer ?? {};
const userPurgeCSSOptions = options?.purgeCSS ?? {};

const targets = browserslistToTargets(browserslist(options?.browserslists ?? null));

const { code } = transform({
filename: 'style.css',
code: Buffer.from(rawCss),
minify: true,
targets,
});

const purgeCSSOptions: PurgeCSSOptions = {
content: [
{
raw: html,
extension: 'html',
},
],
css: [{ raw: code.toString() }],
};

Object.assign(purgeCSSOptions, userPurgeCSSOptions);

const autoprefixerOptions: AutoprefixerOptions = Object.assign({}, userAutoprefixerOptions);

const postcssPlugins: AcceptedPlugin[] = [
purgecss(purgeCSSOptions),
autoprefixer(autoprefixerOptions) as AcceptedPlugin,
cssnano as AcceptedPlugin,
];
const [{ css }] = await new PurgeCSS().purge(purgeCSSOptions);

const minicss = await postcss(postcssPlugins).process(css, {
from: undefined,
});
return minicss.css;
return css;
} catch (error) {
console.error(error);
throw error;
Expand Down
11 changes: 5 additions & 6 deletions packages/tinycss/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@sardine/eleventy-plugin-tinycss",
"version": "1.6.0",
"version": "2.0.0",
"description": "A plugin for 11ty to minify and optimise CSS",
"keywords": [
"11ty",
Expand Down Expand Up @@ -39,11 +39,10 @@
"test": "jest --coverage"
},
"dependencies": {
"@fullhuman/postcss-purgecss": "^4.0.3",
"autoprefixer": "^10.2.5",
"cssnano": "^5.0.2",
"jsdom": "^16.5.3",
"postcss": "^8.2.15"
"@parcel/css": "^1.3.1",
"browserslist": "^4.19.1",
"linkedom": "^0.13.0",
"purgecss": "^4.1.3"
},
"bugs": {
"url": "https://github.com/sardinedev/eleventy-plugins/issues"
Expand Down

0 comments on commit fff9009

Please sign in to comment.