A good asset pipeline can offer your project many benefits. The three main benefits come in the form of concatenation, preprocessing and compression.

Concatenation reduces the number of requests that a browser must make to load your site. Fewer requests can mean improved load times, since each request takes time and browsers can make only a limited number of simultaneous requests.

Preprocessing lets you write assets in higher-level languages such as CoffeeScript, Sass/Scss, Less and Erb. These higher-level languages are designed to produce code that is more maintainable and portable than raw CSS and JavaScript.

In addition to these benefits, a good asset pipeline can also improve project organization through defined asset dependencies and load times through smart browser caching.

With all of the benefits that can come from a good asset pipeline, I was surprised to find that Jekyll does not ship with one. Fortunately, there are plenty of Jekyll plugins available that attempt to fill this gap. Unfortunately, most are hacks that only solve one or two problems. After about an hour of searching Google, it became clear that none of the existing options were going to meet my needs – and I think I have pretty reasonable needs.

What would a good Jekyll asset pipeline look like?

Before I set out to build an asset pipeline, I thought it would be useful to define what I thought a good asset pipeline should offer. The following is the list of requirements that I came up with. A good asset pipeline should…

Integrate seamlessly into Jekyll’s existing workflow. There should be no additional steps required to re-generate a site beyond running the jekyll command.

Bundle multiple assets into a single file based on a manifest of asset dependencies provided in the markup and permit multiple asset bundles throughout my site.

Lightly couple preprocessors and compressors such that upgrades of these external libraries are possible without requiring an upgrade of the asset pipeline.

Be easy to add new preprocessors and/or compressors without having to modify the asset pipeline source code.

Support so-called “cache busters”, the convention of naming asset bundles with MD5 hashes so that browsers expire cached versions when a bundle is modified.

Automatically generate HTML tags that include the bundled assets in the generated site. Allow one to override the default HTML tags with custom markup.

Have a “development mode” that is easy to enable via Jekyll’s “_config.yml”. In development mode, assets should be preprocessed but not bundled or compressed.

Now that is a long list, but I think it is a reasonable spec that resembles the features offered by other asset pipelines such as Sprockets, Jammit and Juicer. If you have other requirements that are not on this list, I’d love to hear them– message me on Twitter or Facebook. With this list in mind, I set out to create an asset pipeline for Jekyll.

Introducing: Jekyll Asset Pipeline

Jekyll Asset Pipeline is a lightweight yet powerful asset pipeline that collects, converts and compresses a site’s JavaScript and CSS assets. It painlessly integrates into Jekyll’s workflow so that there are no additional steps to perform when generating a site. It is installed via a RubyGem so you don’t have to touch its source code. It even works with Jekyll’s automatic site regeneration (i.e. the --auto option).

Asset dependencies are defined in manifests using special Liquid blocks located in your site’s markup. When the site is generated, these blocks are converted into an HTML tags that point to the bundled assets defined by the block. Assets are concatenated in the same order that they are defined in the manifest. Bundled asset files are named with a MD5 fingerprint that automatically expires browser caches when the assets are updated.

Preprocessors and compressors are decoupled from the asset pipeline via extensions defined in the “_plugins” folder your Jekyll project. This allows Jekyll Asset Pipeline to support any preprocessing or compression library without becoming bloated with a bunch of unnecessary dependencies. This also means you can upgrade your preprocessors and compressors without worrying about compatibility issues with Jekyll Asset Pipeline.

Templates allow you to override the default HTML tags produced by Jekyll Asset Pipeline. This is particularly useful when you want to include special attributes (e.g. media or data) in the generated markup.

Credits

As I was creating Jekyll Asset Pipeline, I came across a number of tools that gave me inspiration and showed me best practices, but one stood out in particular– I have to give credit to Moshen for creating the Jekyll Asset Bundler. It is a great library and almost met my needs. I also have to give credit to Mojombo for creating Jekyll in the first place.