Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/metonym/caligula

Optimize CSS stylesheets for your Svelte apps
https://github.com/metonym/caligula

css-classes optimize prototyping stylesheet svelte

Last synced: 26 days ago
JSON representation

Optimize CSS stylesheets for your Svelte apps

Awesome Lists containing this project

README

        

Caligula logo, portrait bust of emperor Caligula

# caligula

[![NPM][npm]][npm-url]
[![Build][build]][build-badge]

> Optimize CSS stylesheets for your Svelte apps.

This library statically analyzes and extracts class selectors from Svelte components using the [svelte compiler](https://svelte.dev/docs#Compile_time). Given an external CSS file, the library outputs an optimized stylesheet by removing unused class rules.

**Table of Contents**

- [Motivation](#motivation)
- [Against Preprocessors](#against-preprocessors)
- [Usage](#usage)
- [Output](#output)
- [API](#api)
- [License](#license)

## Motivation

One of the quickest ways to style Svelte applications (or web apps in general) is to define an external CSS stylesheet in the HTML `head` tag.

```html

```

By design, styles written in Svelte [are scoped to the component](https://svelte.dev/docs#style). While scoped styles improve encapsulation, it is cumbersome to prefix globally applied rules with `:global`.

```html

import Accordion from "./Accordion.svelte";

:global(.line-height-heading) {
line-height: 1.2;
}

:global(.font-size-sm) {
font-size: 0.93rem;
}

```

The problem is that pre-built stylesheets contain far more rules than are actually used. The CSS file for a design system or library can be hundreds of kilobytes, even after minification.

For example, the stylesheet for the [U.S. Web Design System](https://designsystem.digital.gov/) weighs in at **268 kB minified**.

### Against Preprocessors

One solution is to use a preprocessor to import smaller SASS/SCSS partials.

This has two main drawbacks:

- **Extra build configuration**: Using CSS preprocessors involves additional tooling and set-up. This is overkill, especially for rapid prototyping.
- **Still a manual process**: SASS partials must be manually added or removed, which can be inefficient and error prone.

## Usage

Install `caligula` as a development dependency.

```bash
yarn add -D caligula
```

In this example, only several class selectors are used from a localy copy of the [U.S. Web Design System](https://unpkg.com/[email protected]/dist/css/uswds.css) CSS file (unminified).

```js
// postbuild.js
const { caligula } = require("caligula");

caligula({
include: ["src/**/*.svelte"],
input: "css/uswds.css",
});
```

### Output

```diff
node postbuild.js

# Detected 7 classes from 2 Svelte components
# Removed 4660 classes from "css/uswds.css"
- Original size: 357.915 kB
+ New size: 10.53 kB

+ > 347.385 kB (97.1%) smaller!
# > Saved output to "css/uswds.8a6dce134044.css"
```

The output file is minified and hashed. Its size is significantly smaller than that of the original.

## API

```js
caligula({
/**
* glob of Svelte components
* @type {Array.}
*/
include: ["src/**/*.svelte"],

/**
* path to the original CSS file
* @type {string}
*/
input: "css/uswds.css",

/**
* optional output file path
* @type {string} [output=undefined]
*/
output: "dist/uswds.min.css",

/**
* hash the output file name
* @type {boolean} [hash=true]
*/
hash: false,

/**
* cssnano minification config options
* @type {object} [minifyOptions={ from: undefined }]
*/
minifyOptions: {},

/**
* hook triggered after minifying the CSS
* useful for appending metadata like licenses
* @param {string} - minified CSS
* @returns {string} - modified CSS
*/
onMinify: (css) => `/*! uswds v2.6.0 */${css}`,
});
```

## License

[MIT](LICENSE)

[npm]: https://img.shields.io/npm/v/caligula.svg?color=blue
[npm-url]: https://npmjs.com/package/caligula
[build]: https://travis-ci.com/metonym/caligula.svg?branch=master
[build-badge]: https://travis-ci.com/metonym/caligula