Our life is frittered away by detail. Simplify, simplify.
—Henry David Thoreau.
A few days ago, I explained that I was simplifying the site’s look-and-feel. That seemed plain enough, I’m sure.
There was more going on behind the scenes, however.
Story time . . .
It’s been about two-and-a-half years since I first launched this site. It’s been closer to three years since I began research into how I wanted to maintain it. That process ended with my choosing to go with static site generators (SSGs) in general and the Hugo SSG in particular.
Sprinkled in between that short try and longer engagement, not to mention the dalliance with Gatsby, was a brief return to Hugo that was spurred in part by a distrust of all the Node.js dependencies that power both Gatsby and Eleventy. This is as opposed to Hugo, which is a single-binary executable—in plain language, an app.
Nonetheless, I enjoyed JS-based SSGs in general and Eleventy in particular, so I buried such thoughts in the back of my mind and went on my merry way, figuring I’d finally fought the issue to a conclusion.1
Then, starting in the spring of 2020, I had occasion to deal with Hugo once again.
In April, I wrote about incorporating webmentions in one’s Hugo-based website. It was part of a five-part series about webmentions and SSG-based sites, and the research I did for the Hugo-related part allowed me to notice anew some of Hugo’s advantages.
In July, as part of creating some SSG starter sets, I made two for Hugo, and once again found myself enjoying working with Hugo more than I’d expected.
Intrigued by the “what-if” ideas now swirling in my cranium, I thoroughly updated my old Hugo repo, including spiffing it up with themes for both Tailwind CSS and SCSS. I even used it to run this site for a few weeks. Nonetheless, I then switched the site back to Eleventy, figuring that’d been enough of that.
As 2020 neared a merciful end, two things happened that made me re-think that judgment.
Thing One: A wacko repo
One Saturday morning, spurred by curiosity about cache-busting static assets in Eleventy (more on that in Thing Two down below), I began to work once again with the webpack-based Eleventy repo I’d abandoned earlier in the year. Since it had been months since I’d updated all the dependencies, I ran the usual sequence of
npm commands to accomplish that, and then ran
npm run start so the repo would create a dev-mode version of the site.
Or, at least, I’d hoped it would create that. Can you say, “lots of breaking changes”?
Now, this glitchiness was no shock. Among other things, the update took the repo from webpack 4 to webpack 5; and that, alone, accounted for most of the FUBARing. However, quite a few other updated dependencies were equally screwy. I had been prepared to fight a handful of such issues but not a whole host of them, and particularly not in view of my simple lack of knowledge of how to do so.
Slowly, it dawned on me that this was what eventually would happen to any of my repos built on Node.js dependencies, even those with which I did work actively.2 And I began to wonder about how much I wanted to keep fussing with all that.
- “Every separate package adds overhead and another maintainer that you’ve got to put your trust in. I’d rather have few packages of well-trusted maintainers instead of a thousand packages from God knows who.”
- “I have a project with a total of eight dependencies. I walked away for six months as it was stable. I come back to add a few features and npm tells me I have over 38,000 vulnerabilities of different severity levels. So many that
npm auditjust freezes up.”
npmprojects. I came back to a project after a few months and it was broken; had to rewrite some parts and upgrade other parts just to get it to run again.”
- “I’ve had several apps that can basically never be upgraded due to complete insanity deep in their dependency trees. I’m pretty cautious about third-party dependencies, but some of those libraries’ libraries are not, and it’s really hard to see that coming.”
And, of course, there’d once been the infamous
left-pad incident which, while mitigated quickly, constituted a cautionary tale of major proportions about packages that were, themselves, giant collections of packages.
As I considered these things, a little voice in my head periodically whispered, Ya know, you wouldn’t be worrying about these things if you were still using Hugo.3
I soon found myself ruefully recalling my own assessment at the end of “Why I’m staying with Hugo,” the chronicle of my initial foray with SSGs from the world of Node.js:
Thing Two: Asset pipeline envy
One particular Hugo functionality I not only rediscovered but also learned more about during that run-through last fall was Hugo’s built-in asset pipeline, Hugo Pipes. This came to the fore for me after I became more aware of the need for cache-busting static assets. This is something Hugo can do out of the box, while Eleventy has no asset pipeline and therefore must accomplish this through other means.
I spent three separate articles on this subject of cache-busting CSS in Eleventy. Although I finally managed to come up with a mostly satisfactory solution, I once again found myself musing about how ably Hugo, on its own, handles this and so much more for which a Node.js-based SSG needs to depend on, well, tons of dependencies (and, even then, can’t always do what Hugo can do).
The result: Thoroughly Thoreau
After several weeks of these and numerous other considerations, I realized that what I wanted most about maintaining this website, over and above all the technicalities, was to simplify it. And I meant to simplify it for you readers, too, not just for me.
So, over the last few days, I put in place this plan:
- Simplify the site’s appearance. Done.
- Move the site’s hosting from Cloudflare Workers Sites back to Vercel. Done. In my tests over the last half-year, I’ve found that Vercel provides great worldwide performance and the fastest build speeds in the field while requiring no futzing around with GitHub Actions for builds.4
- Take the site back to single-binary land with Hugo. Done. (Well, you probably figured that out some time back in this piece, didn’t you?)5
- Decide what to do about Tailwind CSS. Still in flux. This is the last battlefield of the war between simplicity and FOMO. If FOMO wins on this count, I keep the ultra-popular Tailwind and the PostCSS it requires—even though the two constitute, yep, buckets of Node.js dependencies. If simplicity wins, the site goes back to SCSS, as in the site’s first year-and-a-half under all three SSGs on which it existed during that period.6
At least until I decide that last item, I am maintaining two different themes in the Hugo repo. One is built on Tailwind, and the other on SCSS. (I named them “thoreau” and “thoreauscss,” respectively.) While I continue to consider the choice, I can easily switch back and forth between them with a simple edit to the site’s config file. [Update, 2021-03-01: Decided to go with SCSS, but still have PostCSS for using Autoprefixer.]
Time to let others run
Just when I thought I was out, they pull me back in.
—Michael Corleone, The Godfather: Part III.
The story I’ve related herein may make it appear that over the last year-and-a-half I have, to paraphrase the Red Queen from Alice in Wonderland, been running as fast as I could to stay in the same place. That’s fair.
In my defense, though, I feel the last nineteen months of experience with multiple SSGs and the Node.js universe have been invaluable. I learned a lot and that always was—and remains—the idea, much more so than indulging FOMO.
Nonetheless, there comes a time to let others do the hard running.
To be sure, I can keep reading about, researching, and testing SSGs and other related geeky stuff in the background; and I will, because I’m a curious fellow (in multiple senses of the word curious). But, when it comes to this site, I believe—hope—that I’ve reached a point where I can make myself stop spending so much time and effort futzing with the house’s paint and foundation.
That way, I can work harder on making its interior more comfortable for those of you who visit.
The welcome mat is always out for you.
Note: The more things change, the more they stay the same; see the ending of “Tailwind-to-head with Eleventy” from a few weeks after I issued this post.
Those of you who want to go on an even deeper trip back down Memory Lane on what I ended up calling my “Dance” among SSGs need only check out my end-of-2019 retrospective and, if you’re so inclined, follow its links. ↩︎
As even one of Eleventy’s own maintainers has put it in a GitHub discussion, “Eleventy is basically just a glorified Node.js script.” (And that’s true of all the Node-based SSGs, to be sure.) That’s not necessarily a bad thing, mind you; well-crafted Node scripts can do amazing things. But you have to be able to live with the often wobbly piles of dependencies that such scripts typically require. ↩︎
In fairness, let me observe that even Hugo has a few dependencies in the form of a number of open-source libraries, such as Goldmark for parsing a Hugo site’s Markdown content. The critical difference between Hugo and the Node.js-based SSGs on this score is that Hugo’s relatively small number of dependencies are baked into Hugo rather than being separate things out in the Node.js package universe which one has to hope will behave themselves. ↩︎
I also took another look at the Rust-based Zola SSG, which is essentially an attempt to make a simplified version of Hugo. Zola is another single-binary, Node.js-free platform but has much easier templating, through the Jinja-like Tera, than Hugo’s sometimes maddening Go-derived templating. The latest Zola version I tested has eliminated many of the annoyances I’d discovered earlier but isn’t yet suitable for my purposes. For one thing, I’m not happy with how it handles footnotes—which, as this post makes clear, is an important consideration for this site. ↩︎
Of course, there’s also a possibility that I’ll decide the true route of simplicity for my styling concerns would be to keep the Tailwind/PostCSS combo rather than committing to the somewhat more tedious maintenance of bespoke SCSS. ↩︎