the jamstack build pipeline reimagined

This commit is contained in:
Wouter Groeneveld 2022-11-21 19:22:04 +01:00
parent 777d133a41
commit 54994f91e9
5 changed files with 52 additions and 0 deletions

View File

@ -0,0 +1,6 @@
---
date: 2022-11-20T21:05:44+01:00
context: "https://seblog.nl/2022/11/20/2/ging-goed"
---
Proficiat!

View File

@ -4,6 +4,7 @@ subtitle: Getting rid of iframes and Google Cookies
date: 2021-06-15
tags:
- hugo
- website
categories:
- webdesign
---

View File

@ -6,6 +6,7 @@ categories:
tags:
- hugo
- blogging
- website
- writing
---

View File

@ -5,6 +5,7 @@ categories:
- webdesign
tags:
- hugo
- website
- searching
---

View File

@ -0,0 +1,43 @@
---
title: The Jamstack Build Pipeline Reimagined
date: 2022-11-21T19:14:00+01:00
categories:
- webdesign
tags:
- website
---
As a follow-up to my earlier overview, [Finding Stuff on Big Blogs](/post/2022/11/finding-stuff-on-big-blogs/), I decided to rewrite bits and pieces of Brain Baking by stealing great ideas from others listed in that post---in true Austin Kleon style.
The main thing that changed, besides the _You Might Also Like..._ list below each post containing both backlinks and articles related by tag, is the contents of the [index page](/) which now contains three lists:
1. _Freshly Baked_---the last five bakings a.k.a. blog posts.
2. _Best Sellers_---the buns that fly off the shelves a.k.a. most popular posts.
3. _Random Treats_---five randomly served posts to spice things up a little.
I contemplated adding a _Personal Favorites_ but then I'd have to periodically curate that list and probably forget about it anyway. Too much friction involved.
The first and last are easy enough to achieve in Hugo: `range first 5` and `shuffle`. There, done. But how can I retrieve those best sellers when Hugo, as a static site generator, has zero knowledge of this data? Jim Nielsen does so by [fetching data from Netlify](https://blog.jim-nielsen.com/2020/using-netlify-analytics-to-build-list-of-popular-posts/). This site uses [GoatCounter](https://www.goatcounter.com/) to gather some basic web analytics without cookies or tracking data, so I came up with a script that queries the GoatCounter DB and converts that into JSON[^cur]. I've also opened up the [stats.brainbaking.com page](https://stats.brainbaking.com/) just for fun---go nuts. While Jim lists hits in absolute numbers and Hacker News highlights, I think it's very dangerous to focus on that and went with a relative percentage instead. (Okay, I'll admit: my "popular this month" pageviews net less than `1K`. But who cares, right?)
[^cur]: If you're interested in the details, see https://git.brainbaking.com/wgroeneveld/brainbaking/src/branch/master/extras.
Woah there. Back up a bit, how does that _dynamic_ data make it into the ["Jamstack"](https://jamstack.org/), a fancy name for a set of Javascript and API tools a _static_ site such as this one runs on? By adding pre- and post-processing steps. For instance, Pagefind is [a post-processing step](/post/2022/08/implementing-searching-in-static-websites/), and so is sending Webmentions.
The idea is as follows:
1. **Write**---You write stuff in Markdown. Great! High five! But that `.md` won't cut it---it needs to be converted into `.html` and served.
2. **Precompile**---Run custom scripts to generate extra data needed to create HTML files, such as the popular posts or a list of webmentions in JSON format or the [conversion of YouTube links to images](/post/2021/06/youtube-play-image-links-in-hugo/), allowing Hugo to correctly interpret these.
3. **Compile**---Use Hugo, Eleventy, Jekyll, whatever to build a folder of files that a web server can serve to your visitors. Great! Now you have a `docs/` dir full of HTML and CSS! Now what?
4. **Predeploy**---Run custom scripts to generate extra _raw files_ needed to deploy and host without having them parsed by your generator. Files such as Pagefind's search index fragments.
5. **Deploy**---Copy that folder to your server into `/var/www` and point a web server like Nginx, Caddy, whatever to that folder. Great, now people can surf to your domain and view the site!
6. **Postdeploy**---Run custom scripts that should trigger once the site is up-to-date. Scripts such as sending out new Webmentions, parsing your updated RSS feed, sending a mail, whatever.
Compared to dynamic website builders such as Wordpress, Jamstacks are quite simple: it's only HTML/CSS/JS. That can be quite frustrating if you want to inject data that lives outside of your repository. By enriching the source _and_ destination folders, you can still exert control and make things "dynamic", even though they're not. The "random treats", for example, doesn't ever change, unless Hugo rebuilds the site---which is triggered once an hour if there's a new commit in the repository.
I know this all sounds awfully technical, and it probably is. But don't let the limitations of a typical Jamstack approach be a burden: just hack your way around it. Most of the above steps are optional: only _write_, _compile_, and _deploy_ are required and can be simple one-liners.
The above steps simply get executed by calling upon [bun](https://bun.sh/)---you _are_ using the much faster `bun` instead of `yarn` or `npm` now, right? `bun compile` adheres to the [Npm lifecycle](https://docs.npmjs.com/cli/v9/using-npm/scripts) and automatically runs scripts with `pre` before and `post` afterwards. By keeping the commands inside my `package.json`, each of my websites gets to do other custom stuff on each of the above steps, without having to change the deployment procedure.
For every script or custom hack I paste onto this pipeline, I first think: _is this really needed?_ By using the default build pipelines, I've actually cleaned up the mess and made things less complex than before, although that perhaps isn't entirely obvious.
Remember: [Reducing Your Workflow Load Facilitates Writing](/post/2021/07/reducing-workflow-load-facilitates-writing/)! If it takes a few battered-together scripts, then it takes a few scripts, who cares!