A Laravel (and Statamic) asset cacher for including non-hierarchical JS/CSS dependencies

A WHAT NOW?!!!

Note: If this has been done before, just tell me and point me in the right direction please? Thanks!

TL;DR

I made a Laravel package and Statamic v3 addon that automatically download JS and CSS package files from CDN’s and cache and serve them locally.

Go straight to the README’s if you’re interested, or read on if you don’t quite understand what this is or why you might want it.

Background

I’m LOVING some of the trends in my tech world right now:

  • No JS
  • Less JS
  • Simpler JS
  • Vanilla JS

Not that I hate on JavaScript. It’s powerful, popular, easy (maybe deceptively so!) and has changed the internet for the better. But do we overuse it? Are we too dependent on it?

Anyway, it’s all good stuff. And (fanboy moment) a lot of the chatter on this in my world is powered by the brilliant Caleb Porzio and his Laravel Livewire and AlpineJS projects and all the amazing content he’s putting out around these topics.

Ditching the Build

I, personally, am on a “Ditch the Build” trend. Trying to figure out how, if at all, we, as web developers, can wean ourselves off of starting every project with npm install; of acquiring the technical tooling debt that we inevitably acquire in using build tools; and of simplifying the back-end of the front-end development experience.

I want to say up-front that “Ditch the Build” is NOT for ALL projects: npm, webpack, parcel and so on are powerful tools that HELP us in many cases. But do we really need them for building simple websites and WordPress themes?

Have things like CSS custom properties, ES6+ JavaScript, promises, async/await, the fetch API, HTTP2 and a multitude of others all made NOT having a complex build process possible for smaller projects?

Losing your dependencies

One issue that has not been resolved in my mind about how to Ditch the Build is including JavaScript dependencies.

We all want our included code to be up to date and package managers help with this. But if I just want to include a JS library file from somewhere, I need to keep it up to date manually.

Options are:

  • Use npm/yarn/whatever and include the dependency manually; seems like overkill for including a JS file.
  • Use an npm wrapper like Laravel Mix; more overkill because you’re including webpack and other stuff; but, it gives you an asset tag to include the dependency which may be a bonus.
  • Use Bower, which, though still maintained, is technically deprecated and not recommended.
  • Use a CDN and include the script tag manually; fine, but there are several good reasons not to do that (see below).
  • Just download the script and include it manually.

Clearly if you’re trying to ditch the build then only the last two options here are usable.

And the problem with CDN’s is that, while there may be slight performance gains, you become dependent on a third party for your site to work. CSS Wizard Harry Roberts gives a multitude of reasons not to use a CDN. And you still have to manually update the script tag if you want to update it. (Yes, not even the major CDN’s support “latest version” – remember this, we’ll come back to it!)

Idea: An automatic asset cacher

So I had this idea: could we automate the process of downloading an asset (JS or CSS) from GitHub or from a CDN and then caching it and serving it locally?

Could I just have some kind of helper function or Blade (or Antlers, for Statamic) tag that would output a link to this automatically locally-cached copy?

And could it maybe have a package-manager-link version constraint so it could automatically use minor updates? (Yes, in retrospect, this might be a bad idea).

Could we just do, for example?:

<script src="{{ assetCache(<package>, <version>, <file>) }}"></script>

It’s alive!

Yes, yes, this isn’t big or clever. But here you go:

It has some limitations, and may not actually save you that much time. But I think it’s kinda neat.

Why is this a big deal?

You’ll see this in readme’s, but this is a big deal for me because:

  • This is my first (and second) Laravel package
  • This is my first Statamic addon
  • I’ve had to learn quite a lot to accomplish this – nothing hard, but just lots of little things. (Huge thanks to Marcel Pociot‘s excellent PHP Package Development course for guiding me through!)

I’m not sure if these are useful to anyone; if this idea actually has any merit. But they were a good exercise in creating and publishing packages and addons. Constructive feedback is welcome!