In the past year I was doing some work for a client where I was taking over maintenance of their Wordpress install. The previous devs had used Sage, a framework I was familiar with… but also, the version they’d used was pretty old, and furthermore, old to the point that the build tools used in that version were no longer maintained. Moving the whole thing over to the newest version of Sage seemed more trouble than it was worth given the changes to templating, but I wanted to see if there was stuff I could borrow and back-patch in.
The newer versions of sage use Bud for asset compilation, which is a build tool that’s so weirdly easy to use sometimes that I often forget it just… works. I installed bud
and then also the plugins bud-imagemin
, bud-postcss
, bud-preset-wordpress
and bud-sass
, put together the bud.config.mjs file, and then set the package.json build
script to run yarn bud build
. And this is all that I put in bud.config.mjs:
/**
* Build configuration for bud.js
* @param {import('@roots/bud').Bud} bud
*/
export default async bud => {
/**
* The bud instance
*/
bud.postcss.setPlugin("autoprefixer");
bud
/**
* Set the project source directory
*/
.setPath(`@src`, `assets`)
.assets(["images", "fonts"])
.minimize()
.hash()
/**
* Set the application entrypoints
* These paths are expressed relative to the `@src` directory
*/
.entry({
app: [`scripts/main.js`, `styles/main.scss`],
old: [`css/all.css`], // [`./sources/app.js`, `./sources/app.css`]
})
}
First I tell it that we’re using the postcss autoprefixer; then, I tell it what path to use to look for assets, include the images and fonts folders in the set of assets to copy over, tell it to minimize everything possible, and also add a hash for caching reasons. (Originally I wasn’t using that, but we were having problems with the admin staff not seeing things update immediately due to our caching solution, and that was easier than telling them how ctrl+shift+r works.)
Since I don’t have static filenames because of the hashing, I also have to add a little helper function on the php side:
function asset_path($filename) {
$dist_path = get_template_directory_uri() . '/dist/';
$directory = dirname($filename) . '/';
$file = basename($filename);
static $manifest;
if (empty($manifest)) {
$manifest_path = get_template_directory() . '/dist/' . 'assets.json';
$manifest = new JsonManifest($manifest_path);
}
if (array_key_exists($file, $manifest->get())) {
return $dist_path . $directory . $manifest->get()[$file];
} else {
return $dist_path . $directory . $file;
}
}
This takes a filename, checks it against the manifest that bud.js generates, and then returns the actual full file path, presuming it exists, which makes sure you get the up-to-date version of the file every time.
The application entrypoints are the stylesheets and scripts that call a bunch of other stylesheets and scripts; in this case I’m compiling the newer scripts/main.js
and styles/main.scss
as well as a few old files that I hadn’t yet refactored, which get compiled separately under the old
group.
The whole thing runs in a couple seconds on my M2 mac, compared to some of the older 30-second build processes I used to do and is just generally really snappy. I’ve never really understood webpack and find its documentation really opaque; the Bud.js docs leave a little to be desired when you’re trying to do something more unusual, but the fact that for most circumstances it configures right out of the box and just works is so nice.
other reads from my follows
Festival of Spring and Dawn
The Wheel turns to Ostara.
via Frills - Blog & experiments March 19, 202520 years of YC
I saw recently that YCombinator celebrated its 20th anniversary. Hacker News is slightly younger, but to me the two go hand in hand. As far as I can tell, I actively started reading Hacker News around 2011. I don’t remember how I heard about it. It was prob…
via Normcore Tech March 18, 2025Please stop externalizing your costs directly into my face
This blog post is expressing personal experiences and opinions and doesn’t reflect any official policies of SourceHut. Over the past few months, instead of working on our priorities at SourceHut, I have spent anywhere from 20-100% of my time in any given wee…
via Drew DeVault's blog March 17, 2025generated by openring