Concatenate JS for Free with Jekyll

Apr 15, 2018
Tags: Jekyll Web Development

This one’s a stupid little trick, but I literally use it all the time, and I’m always surprised how novel people find it when I explain it to them. Basically: use Liquid includes in a bundle.js file, and let Jekyll smash all your .js crap together for you.

Jekyll will parse any file that has a YAML front matter block at the top of the file. So, just drop one of those suckers at the top of your JS file and include your scripts in the order you need them.



{% include _vendor/turbolinks.js %}
{% include _vendor/isotope.js %}

//More Awesome JS Stuff Below

When Jekyll hits bundle.js it will grab your partials and drop them into the file right where they should be. You may still want to minify, etc.—though your vendor files are probably already ugly. This is a super simple, no overhead, low config way to concatenate all your js crap together—letting Jekyll do what Jekyll does best: parse files.

Viewing AWS logs on the Command Line

Mar 28, 2018
Tags: Serverless Web Development

If you’ve ever tried to quickly check AWS logs from the command line then you know my pain. Don’t get me wrong, the AWS CLI is great and all but—if I just want to quickly double check that a Lambda function has returned what I think it has—it’s kind of a giant pain in the ass. You’ve got to first describe-log-streams for a given log group, grep to find the most recent stream and capture the logStreamName, then get-log-events for the stream (requires logStreamName), and then finally grep for what it is you were hoping to find.

I’d say that this was basically like “living in Mogadishu”—but then I’d have to punch myself in my first world face—so I’ll just say that it’s less than ideal. So, recently I’ve been using awslogs, a nice little Pyhton utility for doing the same type of thing—only more better.

Why better? Because you can do the same thing as above, in a single command.

awslogs get /aws/lambda/myGroup 2018/03/28 -s2h | grep objectIDs -C 1

Basically: get events for the given log group, where streams match the given expression, in the given timeframe—then grep for what I’m hoping to find. I’m sure there must be a better way of doing this kind of thing that I’m totally unaware of but, “works for me”™.

Git Branch in the Bash Prompt

Feb 25, 2018
Tags: Command Line Tooling

Waaaay late on this one—but you know what they say. For a while I’ve had a text trigger in iTerm2 to catch and highlight the currently active Git branch—but it never occurred to me to just add it directly into the command prompt.


Trivial to do, and super helpful—as soon as you open up the directory, you immediately know what branch you’re working in. Below is what the setup for the prompt looks like, just drop that into your .bash_profile and you’re all set.

parse_git_branch() {
     git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ (\1)/'
export PS1="⚑$RED\$(parse_git_branch) $NO_COLOR\w > "

VS Code: Hope, Hype, and Hijacking

Feb 21, 2018
Tags: Tooling Text Editors

I’ve always been a bit promiscuous with my text editors. The whole chronology probably looks a little something like this:

Dreamweaver => Coda => BBEdit => TextMate => Espresso => Sublime Text => Espresso (again) => Sublime Text 2 => Atom => TextMate (again) => BBEdit (again) => Sublime Text 2 (again) => Espresso (yet again) => Sublime text 3 => Atom (again) => Espresso (yet again, again) => Sublime Text 3 (again) => VS Code.

As you can see, I’m not shy about “picking up stakes” and moving from one to another—and back again. I’d like to think that I’m always hopeful for better features, performance, extensibility, etc.—that I’m always looking for ways to procrastonate, and avoid acutally doing any work with the editor du jour is probably closer to the mark. Nevertheless, my promisquity has given me a pretty good sense for what does and doesn’t make for a good editor.

Espresso App

From a purely UI/UX perspective I still think Espresso is one of the most elegant editors I’ve ever used—unfortunately its workflow model is a bit anachronistic. I really appreciate the thought that went into some of the features like Dynamo—their proprietary static site generator—but ultimately, it’s playing in the proverbial walled garden. And, I can’t remember the last time I used FTP to send files to the server.

Like most, I’ve welcomed our new decoupled, extension based, Git enabled, Electron App overlords—and it’s probably for the best. Electron apps will never be as blazingly fast as a well written native app, but VS Code does “OK”—better than Atom, I think. The Git integration is nice, though I do most of that stuff from the command line anyway. What really gets me are the extensions and the configuration. Granted, it’s a pain in the ass to setup—Sublime is too—and though VS Code makes it easier than most, it still takes a real investment to get everything configured as you’d like. But the good news is that everything, and I mean everything is configurable, and the extensions are killer.

Killer Extensions

All the usual suspects are there: git gutter, file icons, linting, Emmet, syntax highlighting for every language you can imagine (these are much easier to fine-tune to your liking in VS Code). The IntelliSense—Microsoft’s version of code completion/hinting—extensions are what really seal the deal though.

VS Code

Sure, you get hinted to the right method in Ruby, or ES6—but better than that, you can autocomplete on filenames, CSS class names, even Sass variable, mixin, and function names—I never remember that stuff. There’s no lack of hype around VS Code right now—but on the whole, I’d say it’s living up to it.

Hijacking the Community

Honestly, I feel kind of bad for the Sublime Text folks. Atom, and now VS Code are in many ways a direct hijack of the package/plugin/extension approach—pioneered in TextMate and brought to scale in Sublime—to say nothing of the command pallete, and some other directly hijacked bits of UI. It’s telling that the extension which ports Sublime keyboard shortcuts over to VS Code already has 1/2 a million downloads. But just like any other suffeciently advanced technology these days—it’s the ecosystem that really matters. When TextMate was TextMate, there was a vibrant community around it—creating bundles, themes, and addons—this made the editor much more than it could have been on its own. When development of newer versions stalled, the community moved on to Sublime—and did it all over again. Today VS Code has the community mindshare, but what came before is never really lost—most of the syntax files I’ve seen for VS Code are still based on the original TextMate Grammar scheme from 2004.

Busting CSS Cache with Jekyll

Feb 16, 2018
Tags: Jekyll Ruby

If you’re setting long expires headers on your static assets—as God demands—then at some point, you will want to bust that browser cache. If you’re also using Jekyll, there’s a plugin for that. Here’s the thing though: not everyone needs a full-fledged, sprockets based, asset pipeline for their project. In the world of Jekyll—I’d actually say that the majority of folks don’t need that particular sledgehammer. It adds quite a lot of complexity to your build and, to be fair, the documentation is a bit inscrutable.

There’s nothing wrong with simple workarounds like this:

<link rel="stylesheet" href="/css/main.css?{{site.time | date: '%s'}}">

Which uses the site.time variable formatted as seconds since the epoch (1970). When outputed, the ?1518881511 query paramater gets appended to the end of the filename—browsers see this as a new asset and download it. This is great, and will bust browser cache of the file everytime the site is built.

A Middle Path With MD5 Hashing

Ideally though, you’d only invalidate the browser cache when your asset has changed somehow. You could manually increment when changes occour using semantic versioning e.g. main.css?v=1.2—but my Mtv addled brain would never remember to do that. Somewhere between a Rails asset pipeline and manually incrementing—lies a middle path. A custom plugin that reads in your _sass files, geneartes an MD5 Digest—and then lets you append that digest to your css filname with a filter, e.g.:

<link rel="stylesheet" href="{{ site.baseurl }}/assets/css/{{ 'site.css' | bust_css_cache }}">

Which will give us something like this in the markup: <link rel="stylesheet" href="/assets/css/site.css?c86a8588967580cc0631f5115d9d6b18">. This way, the hash at the end only changes when the content of your Sass files change. A browser could hold onto your stylesheet for a year—but as soon as you make a change to the _typesetting.scss partial, it will ask for the new version.

It’s not as complicated as it sounds. You can add a custom plugin by including an .rb file in the _plugins directory at the root of your project. There are some caveats though, so first have a look at the documentation for running with custom plugins. Plugins can get pretty complicated, but for our purposes we just need to register a simple filter with Liquid.

module Jekyll
  module CacheBust
    # put the stuff that does stuff here


Basically, Liquid Filters take an input and return an output. In our case, our input will be the name of our CSS file, and the output will be the name of our CSS file with an MD5 Digest of our Sass files appended to it. I dropped the full plugin into this gist if you want to give it a look. The key bits are a CacheDigester class that will take a file or directory of files and generate a digest, and the bust_css_cache method which you call as a filter in Liquid.

We’re passing our _sass directory to the CacheDigester object because we write in Sass and our CSS file will only be generated at the end when the site is built. I keep my Sass files in assets/_sass so if you plan to use this plugin you may have to change that bit in the bust_css_cache method.

Simplicity, and Context

What I love about Jekyll, is what I love about Liquid, is what I love about Ruby, is what I love about Vue. They all do complex things, but offer simple affordances to the user. Extending the functionality of Liquid and Jekyll is relatively straightforward, as you can see above. This means you can build the right solution for your particular context—without being forced to use a sledgehammer to swat a fly.

The Distress Signal is the personal blog of Bryan Schuetz. I've been complaining on the Internet since the 90s, AMA—dispatch your courier électronique.