Interview: Talking Middleman V4 and Front-end Dev with Thomas Reynolds
A chat with the creator of Middleman
If you’re not familiar with Middleman, it’s one of the most popular tools out there for building static sites — it’s a framework sort of like Rails, but instead of running it on top of a web server backed by a database, you use it to build out a collection of static files that you can then load directly onto a CDN and serve quickly and securely.
For sites that don’t update very often, static is definitely the way to go. You get speed, stability, and iron-clad security because there’s no server that can get compromised.
A few months ago I had a great chat with Middleman’s creator, Thomas Reynolds of Instrument.com. Thomas and I talked about a lot of things, but we specifically focused on the relatively recent announcement about Middleman Version 4.
Version 4 has been a long time coming, and it brings with it some big changes. In the portion of our conversation excerpted below, Thomas talks through some of the major changes and the rationale behind them.
Jon Stokes: Let’s talk Middleman. Walk me briefly through version 4 and some of the major changes. What was behind that.
Thomas Reynolds: The primary goal was an internal refactor, and this took about two years because there wasn’t really a deadline. Version 3 was very stable and pretty much solved almost everyone’s needs for the platform, but it had just accrued over about six years of pull requests — a lot of garbage and cruft in the system. So it was becoming increasingly hard for anyone to go in there and fix bugs, or to understand what’s going on.
I started Middleman over eight years ago, so I wanted to apply things I’d learned over six of those years to clean up the codebase and make it a better place for people who actually work with modern Ruby.
So for the first year, I just replaced a bunch of pieces that were global and singleton-based with much more instance-based stuff. One of the big wins from doing that is that Middleman can run much more in parallel, because it’s not sharing all these pieces of state across singleton objects.
Then as people started requesting new features over the course of that rewrite, things became so much more simple with the new internals that they ended up just getting added on to what became version 4.
About halfway through that, as myself and other people were cleaning up stuff, we realized there was a bunch of duplicated functionality — a bunch of features that had snuck in through a pull request that nobody was really using or documenting. We tried to remove as many features that could be done in either user code, through extensions, or were already being done by another piece of the system. There’s a lot of removed functionality that has replacements people can still use if they were reliant on that functionality, but it’s a lot smaller and cleaner codebase.
Somewhere near the end of the refactor, maybe the last six months, new features started to pile up. Most of them are in the upgrade documentation. For one, we separated the concept of the environment that you’re operating in — whether you’re building for production or staging. So you can have all these different Rails-style environments now, and you can say “this is my testing build”, “this is my QA build”, or “this is my production build”. It’s a lot easier to keep all those separate since you can use environments to keep all those config options together.
We used to have only one concept — whether you’re in dev mode or you’re building the site. Now we have two concepts: you have your environment with a bunch of config, and then you have your mode, which is again whether you’re running locally or whether it’s building static files.
We go away from the concept of using RubyGems for default templates. The Middleman directory has a hundred custom templates that people use, and at work we have our own starter kits. Now they all just pull down from a Git repository, so when you boot up a new Middleman project you can just point it at your repo. You can get it from Git rather than having to publish a gem, which most people don’t want to do or don’t have time or understanding about. (Especially since a lot of these templates are coming from people who use things like Bootstrap and Foundation, and they don’t want to get into the nitty gritty of Ruby — that’s why they’re probably using Middleman in the first place. So they can just make a Git repo and clone from there over and over again.
JS: There’s the asset pipeline stuff…
TR: Yeah, that’s actually a big one. Basically, the Rails asset pipeline is probably the worst third-party API I’ve ever had to work with in my life. Around the time Rails 3 was coming out, it would just break our build every week or two, just from crazy API changes or complete refactors on their side. I just couldn’t bring myself to support it anymore, and none of our projects here actually use it, so it kind of fell by the wayside.
What I did in the core is open up an arbitrary API that says, “we know you’re going to have a whole pipeline of different tools you need to use, and not just one all-in-one solution.” Trying to make Middleman all-in-one requires too many features to support and too many edge cases.
We added this concept of the external pipeline, which is basically just a subcommand. You can run as many of them as you want and Middleman will orchestrate them. So you can have a SASS compiler over here doing SASS things, and Grunt doing your source maps. It’s a lot more pick-and-choose and a little less straightforward for the base case. But, at least to me, it seems like the ecosystem for front-end stuff is kind of leaving Ruby behind and this is basically the best way to allow people who still want to use Middleman to use things like npm and Node, as well.
JS: We’re currently playing around with React and Rails, and all of the asset stuff has turned out to be a huge headache.
TR: The last straw for me was when they completely rewrote Sprockets for version 3, which meant that all the old gems were no longer valid. I tried to update our support to the new version, but they removed a bunch of features. The only reason I updated it was because they said they were going to have source maps, but then source maps missed the version 3 launch. So it’s like, “you did all this stuff and you still didn’t add the only feature that I needed from you.”
The asset pipeline support is still there — it’s still buggy and is not officially supported.
Ruby, React, and the Future of the Front End
There’s a lot of heartache that goes into working with Node, specifically. Maybe they’ll polish it up soon, and we’ll look back and these will be the hard days. May everything will make sense in a couple of years, but I don’t know.
JS: So are you guys doing a lot of React at Instrument?
TR: We do a little bit. We’re all over the place. We have internal projects in React, and we’re doing a bunch of React Native stuff for iOS right now.
It’s really great. React is quite hard — they give you so few of the things you need to build an actual app. It feels really clean and minimalist. It’s really fun to work in, but if you go build an actual app, you end up with this huge codebase of all these extensions and data libraries and data layers. That’s fine if you’ve got the time for that.
But React Native, it has one single purpose, and all that stuff that you need to add on normally is already there in iOS. So you can just crank out views and apps in React Native easily.
Thomas and I talked about a number of other CMS-related things, which I’ll publish as a sequel to this piece. So look for that, soon. In the meantime, go check out Middleman — if you’re looking at static sites as an alternative to hosted solutions, then Middleman should be at the top of your list.