Skip to content

Commit

Permalink
Drop options.postcssPlugin from API
Browse files Browse the repository at this point in the history
  • Loading branch information
metonym committed Mar 18, 2024
1 parent c77885f commit d308b04
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 75 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ node_modules
dist
build
public/build/
.svelte-kit
.svelte-kit
*.tgz
30 changes: 12 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ export default {

#### Rollup

This code is abridged, see [examples/rollup](examples/rollup) for a full set-up.
This code is abridged; see [examples/rollup](examples/rollup) for a full set-up.

```js
// rollup.config.js
Expand All @@ -121,7 +121,7 @@ export default {

#### Webpack

This code is abridged, see [examples/webpack](examples/webpack) for a full set-up.
This code is abridged; see [examples/webpack](examples/webpack) for a full set-up.

```js
// webpack.config.js
Expand Down Expand Up @@ -197,7 +197,7 @@ export default {

#### Rollup

This code is abridged, see [examples/rollup](examples/rollup) for a full set-up.
This code is abridged; see [examples/rollup](examples/rollup) for a full set-up.

```js
// rollup.config.js
Expand All @@ -220,7 +220,7 @@ export default {

#### Webpack

This code is abridged, see [examples/webpack](examples/webpack) for a full set-up.
This code is abridged; see [examples/webpack](examples/webpack) for a full set-up.

```js
// webpack.config.js
Expand All @@ -241,32 +241,26 @@ module.exports = {
```ts
type OptimizeCssOptions = {
/**
* Set to `false` to disable verbose logging.
* By default, the plugin will log the size diff
* between the original and optimized CSS.
*
* Set to `false` to disable verbose logging.
* @default true
*/
verbose?: boolean;

/**
* By default, the pre-compiled Carbon StyleSheet will
* ship @font-face rules for all available IBM Plex fonts,
* many of which are not used in the Carbon Svelte components.
* As such, the default behavior is to only preserve IBM Plex fonts
* with 400/600-weight and normal-style @font-face rules.
* By default, pre-compiled Carbon StyleSheets ship `@font-face`
* rules for all available IBM Plex fonts, many of which are
* not actually used in Carbon Svelte components.
*
* The recommended optimization is to only preserve IBM Plex
* fonts with 400/600-weight and normal-font-style rules.
*
* Set to `true` to disable this behavior.
* @default false
*/
preserveAllIBMFonts?: boolean;

/**
* Optionally provide a custom PostCSS plugin.
* This plugin will be applied after Carbon Svelte CSS is optimized.
* This is exposed for convenience and maximum flexibility.
* @see https://postcss.org/docs/postcss-plugins
*/
postcssPlugin?: postcss.Plugin;
};
```

Expand Down
10 changes: 2 additions & 8 deletions src/OptimizeCssPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,12 @@ import { components } from "./component-index";
import { CarbonSvelte, RE_EXT_CSS, RE_EXT_SVELTE } from "./constants";
import type { OptimizeCssOptions } from "./optimize-css";
import { postcssOptimizeCarbon } from "./postcss-plugin";
import { logComparison, noop, stringSizeInKB } from "./utils";
import { logComparison, stringSizeInKB } from "./utils";

class OptimizeCssPlugin {
private options: OptimizeCssOptions = {
verbose: true,
preserveAllIBMFonts: false,
postcssPlugin: undefined,
};

public constructor(options?: OptimizeCssOptions) {
Expand All @@ -23,13 +22,9 @@ class OptimizeCssPlugin {
if (options?.preserveAllIBMFonts === true) {
this.options.preserveAllIBMFonts = true;
}

if (options?.postcssPlugin) {
this.options.postcssPlugin = options.postcssPlugin;
}
}

private apply(compiler: Compiler) {
public apply(compiler: Compiler) {
const { webpack } = compiler;
const { Compilation, NormalModule } = compiler.webpack;
const { RawSource } = webpack.sources;
Expand Down Expand Up @@ -69,7 +64,6 @@ class OptimizeCssPlugin {
const optimized_css = postcss([
postcssOptimizeCarbon({ ...this.options, css_allowlist }),
discardEmpty(),
this.options.postcssPlugin ?? noop,
]).process(source).css;

const original_size = stringSizeInKB(source.toString());
Expand Down
32 changes: 9 additions & 23 deletions src/optimize-css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,56 +5,43 @@ import type { Plugin } from "vite";
import { components } from "./component-index";
import { CarbonSvelte, RE_EXT_CSS, RE_EXT_SVELTE } from "./constants";
import { postcssOptimizeCarbon } from "./postcss-plugin";
import { logComparison, noop, stringSizeInKB } from "./utils";
import { logComparison, stringSizeInKB } from "./utils";

export type OptimizeCssOptions = {
/**
* Set to `false` to disable verbose logging.
* By default, the plugin will log the size diff
* between the original and optimized CSS.
*
*
* Set to `false` to disable verbose logging.
* @default true
*/
verbose?: boolean;

/**
* By default, pre-compiled Carbon StyleSheets ship `@font-face`
* By default, pre-compiled Carbon StyleSheets ship `@font-face`
* rules for all available IBM Plex fonts, many of which are
* not used in the Carbon Svelte components.
*
* The recommended optimization is to only preserve IBM Plex fonts
* with 400/600-weight and normal-font-style rules.
* not actually used in Carbon Svelte components.
*
* The recommended optimization is to only preserve IBM Plex
* fonts with 400/600-weight and normal-font-style rules.
*
* Set to `true` to disable this behavior.
*
* @default false
*/
preserveAllIBMFonts?: boolean;

/**
* Optionally provide a custom PostCSS plugin.
* This plugin will be applied after Carbon Svelte CSS is optimized.
* This is exposed for convenience and maximum flexibility.
* @see https://postcss.org/docs/postcss-plugins
*/
postcssPlugin?: postcss.Plugin;
};

export const optimizeCss = (options?: OptimizeCssOptions): Plugin => {
const verbose = options?.verbose !== false;
const preserveAllIBMFonts = options?.preserveAllIBMFonts === true;
const postcssPlugin = options?.postcssPlugin ?? noop;
const css_allowlist: string[] = [".bx--body"];

return {
name: "vite:carbon:optimize-css",
apply: "build",
enforce: "post",
transform(_, id) {
/**
* For all resolved modules that are Carbon Svelte components,
* add the component's pre-indexed classes to the allowlist.
*/
// Append Carbon Svelte component classes to the allowlist.
if (RE_EXT_SVELTE.test(id) && id.includes(CarbonSvelte.Components)) {
const { name } = path.parse(id);

Expand All @@ -71,7 +58,6 @@ export const optimizeCss = (options?: OptimizeCssOptions): Plugin => {
const optimized_css = postcss([
postcssOptimizeCarbon({ preserveAllIBMFonts, css_allowlist }),
discardEmpty(),
postcssPlugin,
]).process(file.source).css;

const original_size = stringSizeInKB(file.source.toString());
Expand Down
20 changes: 7 additions & 13 deletions src/postcss-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,10 @@ export function postcssOptimizeCarbon(
const selector = node.selector;

/**
* This could be improved.
* For now, first ensure that the selector contains a class.
* Ensure that the selector contains a class.
*/
if (selector.includes(".")) {
/**
* Selectors may contain multiple classes, separated by a comma.
* For now, only extract classes.
*/
// Selectors may contain multiple classes, separated by a comma.
const classes = selector
.split(",")
.filter((c) => c.trim().startsWith("."));
Expand All @@ -35,10 +31,8 @@ export function postcssOptimizeCarbon(

for (const name of classes) {
for (const selector of css_allowlist) {
/**
* If at least one class is in the allowlist, keep the rule.
* This is a simplistic approach and can be further optimized.
*/
// If at least one class is in the allowlist, keep the rule.
// This is a simplistic approach and can be further optimized.
if (name.includes(selector)) {
remove_rule = false;
break;
Expand All @@ -53,13 +47,13 @@ export function postcssOptimizeCarbon(
},
AtRule(node) {
if (!preserveAllIBMFonts && node.name === "font-face") {
// IBM Plex Sans and IBM Plex Mono are the only fonts used in the Carbon Svelte components.
// IBM Plex Sans, IBM Plex Mono are the only fonts used in components.
let is_IBM_Plex = false;

// 400/600 are the only weights used in the Carbon Svelte components.
// 400/600 are the only weights used in components.
let is_product_weight = false;

// Only normal-style fonts are used in the Carbon Svelte components.
// Only normal-style fonts are used in components.
let is_product_style = false;

node.walkDecls((decl) => {
Expand Down
24 changes: 12 additions & 12 deletions src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import { BITS_DENOM } from "./constants";

export const noop = () => {};

export const log = console.log;

const formatter = new Intl.NumberFormat("en-US", { maximumFractionDigits: 2 });

export function toHumanReadableSize(size_in_kb: number) {
Expand All @@ -14,15 +10,15 @@ export function toHumanReadableSize(size_in_kb: number) {
return formatter.format(size_in_kb) + " kB";
}

export function percentageDiff(a: number, b: number) {
return formatter.format(((a - b) / a) * 100) + "%";
}

export function stringSizeInKB(str: string) {
const blob = new Blob([str], { type: "text/plain" });
return blob.size / BITS_DENOM;
}

export function percentageDiff(a: number, b: number) {
return formatter.format(((a - b) / a) * 100) + "%";
}

export function logComparison(props: {
original_size: number;
optimized_size: number;
Expand All @@ -33,8 +29,12 @@ export function logComparison(props: {
const optimized = toHumanReadableSize(optimized_size);
const diff = percentageDiff(original_size, optimized_size);

log("\n");
log("Optimized", id);
log("Before:", original);
log("After: ", optimized.padStart(original.length, " "), `(-${diff})\n`);
console.log("\n");
console.log("Optimized", id);
console.log("Before:", original);
console.log(
"After: ",
optimized.padStart(original.length, " "),
`(-${diff})\n`,
);
}

0 comments on commit d308b04

Please sign in to comment.