Kickin - bootstrap your Eleventy project
Tags: eleventy, cli, webdev
Published: 2021-10-18 16:55:52

> Make your web pages fast on all devices - _Developers all over the world._


We always chase productivity on our pages. And Web development community has got many instruments that help achieve this goal. [Eleventy](https://www.11ty.dev) is one of them. It is a great tool that offers an easy way of combining templates and data into fully operative static pages that you can host on a server.

Unfortunately, it can bundle only templates and doesn't care about assets on the site, such as images, styles and scripts etc. So we decided to create a bundler based on Eleventy CLI 🤖
It isn't separate, but we use [Eleventy's events](https://www.11ty.dev/docs/events/) for integration.

The primary tool is [Kickin CLI](https://www.npmjs.com/package/kickin). It quickly bootstraps a template folder with `Eleventy` and necessary plugins for comfortable development. Some of them were built by ourselves:

1. `eleventy-plugin-compress`
2. `eleventy-plugin-pwa-icons`
3. `eleventy-plugin-scripts`
4. `eleventy-plugin-styles`
5. `eleventy-plugin-workbox`
6. `eleventy-shortcode-image`

We don't recommend installing CLI globally. Instead, use a [npx](https://docs.npmjs.com/cli/v7/commands/npx/) for project initialization.

> The minimal required version of NodeJS is **12.17.0**. The reason is that Kickin CLI consists of ES modules.

It exposes command that is named after itself - `kickin`. And its use is pretty simple.

```
npx kickin name-of-your-project
```

If you already have such a folder, you can use the `.` symbol instead of the name.

```
cd my-project-name
npx kickin .
```

Wait until the installation of dependencies completes, and that's all 🤗 

### After

There are four main commands available in the created project:

- `npm start` - starts development server on `http://localhost:3000`
- `npm run build` - builds project.
- `npm run serve` - runs a local server with secure protocol on `https://localhost:3000`. It helps to mimic the production environment.
- `npm run certs` - creates certificates for the ability to run site with HTTPS locally.

> We use [mkcert](https://github.com/FiloSottile/mkcert) to generate SSL certificates. Make sure you installed it on your local machine as well.

You can change any part of the generated project as you want - configuration file and all dependencies are open to being changed.

Let's explore a little bit of what and where CLI installs.

#### Structure

- Source code is located in the `src` folder.

  - `assets`: this folder supposed to be home for static content: images, fonts, video, audio etc.
        * `images`
        * `fonts`
        * `video`
        * `audio`
  - `components` - folder where [Eleventy's components](https://www.11ty.dev/docs/config/#directory-for-includes) are located (default name is `_includes`)
  - `layouts` - folder for [layouts](https://www.11ty.dev/docs/layouts/#layouts).
  - `pages` - place where future site's pages live.
  - `scripts` - folder for scripts that will be used in HTML.
  - `styles` - folder for styles.

- For bundled code, the `build` folder is preserved.

> Inner structure of defined directories is up to you 🙃

Let's dig into plugins a little bit. There are 6 of them.

## [eleventy-plugin-compress](https://www.npmjs.com/package/eleventy-plugin-compress)

This plugin is used to compress `HTML`, `CSS` and `JS` using `brotli`(_default_), `gzip` or `deflate` algorithms. It helps you reduce the size of files that are sent over the internet.

> [Why brotli?](https://wp-rocket.me/blog/brotli-vs-gzip-compression/)

## [eleventy-plugin-pwa-icons](https://www.npmjs.com/package/eleventy-plugin-pwa-icons)

If you want to create PWA,  you will need icons for your application for different platforms. This package uses [pwa-assets-generator](https://github.com/onderceylan/pwa-asset-generator) to create icons from an image. It will automatically insert links to icons into the HTML of every page and in the `manifest.json` file along with generated icons.
All you need is an image as a template for future icons. By default, it is a `favicon.png` under the `src` directory.

## [eleventy-plugin-scripts](https://www.npmjs.com/package/eleventy-plugin-scripts)

Starter supports modern JavaScript syntax (except for Eleventy's templates) and [TypeScript](https://www.typescriptlang.org).

All scripts files should be in the `scripts/` directory, but the inner structure does not matter.

To include scripts into an HTML page, provide `scripts` property in page template's front matter zone (can be either type of _string_ or _array of strings_). The path to the script is relative to `src/scripts` directory, so you do not need to include this prefix in the URI.

```js
// For JavaScript templates
module.exports.data = {
  // This will be resolved to 'src/scripts/main.js'
  scripts: 'main.js', // or 'main.ts' -> 'src/scripts/main.ts'
};
```

## [eleventy-plugin-styles](https://www.npmjs.com/package/eleventy-plugin-styles)

The configuration of this one is very similar to `eleventy-plugin-scripts`.

In _Kickin_ [Sass language](https://sass-lang.com) is supported.

Stylesheets should be in `styles/` directory, but the inner structure does not matter. They will be compiled, minified and cleaned from unused selectors automatically.

To include style to page in the template, provide `styles` property in front matter zone. It can be _string_ or _array of strings_. The path to the stylesheet is relative to `src/styles` directory, so you do not need to include this prefix in the URI.

```js
// For JavaScript templates
module.exports.data = {
  // Bundler of this starter is smart enough to recognize type of style
  // and its location (file will be resolved to `src/styles/home.scss`)
  styles: 'home.scss',
};
```

If you want to put your CSS file in the inner folder, say `directory/common.scss` , don't forget to mention it in your config:

```js
// For JavaScript templates
module.exports.data = {
  styles: 'directory/common.scss', // -> src/styles/directory/common.scss
};
```

It is the most potent package of all! Whew... Amazing!

## [eleventy-plugin-workbox](https://www.npmjs.com/package/eleventy-plugin-workbox)

Adds the [Service worker](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers) that will automatically cache all assets of your site on a client.

> Registration of service worker script will be automatically injected into each HTML page.

By default, the worker will cache static resources (images, fonts, audio files etc.) and try to use them from the cache at first. Dynamic resources that can be changed often (HTML, JS, CSS) are cached also, but on every request, it will try to fetch it on the server at first.

> You can read more about strategies [here](https://developers.google.com/web/tools/workbox/reference-docs/latest/module-workbox-strategies).

## [eleventy-shortcode-image](https://www.npmjs.com/package/eleventy-shortcode-image)

It handles images of your page. It can properly rebase, minify and generate optimal types of images that all browsers support. It uses [@11ty/eleventy-img](https://www.11ty.dev/docs/plugins/image/) under the hood but also can minify SVGs (uses [SVGO](https://github.com/svg/svgo)). Compression is disabled in development mode to reduce build time. You want a quick response on your changes, aren't you? 😊 So, we do too.

For this purpose, the CLI includes an `image` shortcode. Use it to incorporate images to HTML (either raster or vector(SVG) ones).

> Info about shortcodes and how to use them is [here](https://www.11ty.dev/docs/shortcodes/).

Signature of shortcode:

```ts
interface ImageAttributes {
  /** Defines alternative text for image. */
  alt?: string;
  /** Defines title for image. */
  title?: string;
  /** Class name(s) for `class` attribute. */
  classes?: string | ReadonlyArray<string>;
}

async function image(
  src: string,
  attributes?: ImageAttributes
): Promise<string>;
```

The first parameter is mandatory and contains an image path relative to the `src/assets/images` directory.

```js
// For JavaScript templates
module.exports.render = async function () {
  return /* html */ `<main>${await this.image('logo.png')}</main>`;
};
```

For example, _logo.png_ image will be resolved to `src/assets/images/logo.png`, then `webp` and `avif` images will be generated and placed along with the source image in the `build` directory. In HTML, you will receive efficient images with the correct paths 😊!

The same rules apply if you define a path to the image from CSS (for example, in the `URL` function). But if you specify URL as absolute (**absolute public URL**), it will be returned as-is without any changes.

> This is done intentionally in case if you want to copy assets to the output directory.

All these packages are attached to [transform flow](https://www.11ty.dev/docs/config/#transforms) of Eleventy.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qks895vsmxi912nligqn.png) 

> It looks just like above. Every plugin transforms the HTML in its way and could produce new assets. Assets flow separated from Eleventy, but they are synchronised.

### Configuration

The default configuration of Eleventy is enough for most use cases, but sometimes there you need to change some behaviour.

[`.eleventy.js`](https://www.11ty.dev/docs/config/) is a starting point for Eleventy.

If you want to change some behaviour or add new feature to site, place it in `.eleventy/` directory. It has following structure:

- `filters` - used for holding custom [filters](https://www.11ty.dev/docs/filters/).
- `plugins` - contains custom [plugins](https://www.11ty.dev/docs/plugins/) for Eleventy.
- `shortcodes` - contains [shortcodes](https://www.11ty.dev/docs/shortcodes/)
- `transforms` - holds HTML transformer functions that changes generated HMTL by Eleventy.

Feel free to try it and give us feedback. We fell in love with these tools, and we hope you will too 🖤

### Useful links:

1. [This is a repository where a code of all plugins live.](https://github.com/Halo-Lab/eleventy-packages)

**Have fun! ✌️**

_Supported by [Halo Lab](https://www.halo-lab.com) design-driven development agency_