carly.website

/

Blog

/

Easy build tooling with Bud.js

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

A quintessentially Canadian experience

A quintessentially Canadian experience Apr 30, 2024 I guess I haven't share yet on this website, but I live in Toronto. Today, I had such a stereotypical yet cute Canadian experience. I had a deadline that I was working to meet all day. I was pretty stress…

via sorbier April 30, 2024

Prettify Hugo RSS Feeds with XSLT

I put in some work several months back making my sure my site's RSS would work well in a feed reader. This meant making a lot of modifications to the default Hugo RSS template. I made it load the full article text rather than just the summary, present…

via runtimeterror April 30, 2024

How I search in 2024

We are now in a very weird liminal space in information retrieval for consumers, particularly those attuned to trends in search and working on the bleeding edge of LLMs. On the one hand, we have the fall of old companies. Broadcast-based centralized social…

via Normcore Tech April 25, 2024

generated by openring