Anyone know how to run an arbitrary command at the start of the #RubyOnRails asset pipeline process? I want to hook in to build an included javascript file on the fly, but my search-fu is completely failing me...
for one thing, I completely forgot there are now a thousand ways to run the JS asset pipeline. Turns out I'm using `jsbundling-rails`, maybe I should read *those* docs.
What do you mean there's a perfectly simple yarn task that builds my javascript... oh, hmmm. Well, I'll just pop it on the front of that then. Um.
I remain of the opinion that by having multiple ways to do The Thing, Rails 7 makes it much more complex to work out what to do, and in this case, remember what you DID. That's never been The Rails Way.
@Floppy it is the JS way!
@floppy we've gone through jsbundling-rails and cssbundling-rails like a dose of salts. We've removed both of them. All they really do is provide a couple of rake tasks each, like `javascript:build`. We brought those rake tasks in-house to call yarn, then fell back on plain old rake file tasks.
Got a working example if'n you want it.
@floppy oh, one other thing jsbundling-rails "helpfully" does is 'enhance' RSpec and MiniTest by prepending the asset build so that you always have up-to-date assets on test.
This means your asset pipeline build gets run before every test run. We noped out on this with plain old Rake file tasks for (largely symbolic) application.js and application.css (which don't get built when not out of date).
The state of the Rails asset build pipeline is Not That Great rn.
@floppy here's a gist with some documented rationale behind this approach, and the associated assets.rake. We love esbuild, so this approach may work for you.
https://gist.github.com/rgarner/95c484d3534badf269219881013650a4
@rgarner I'm not entirely sure I'm not just using esbuild as well. It's confusing, and I never have time to understand it as long as it works...
@floppy I realised the gist was missing some context, chiefly the "scripts" bit of package.json. I've bunged in our two esbuild configs for JS and CSS as well.
Effectively, all assets are built with JS/yarn via the scripts bit of package.json, and assets.rake is a thin wrapper over the top of that to prevent assets being rebuilt on every test run.
And yeah, it's a lot. But I kinda like where we ended up.
It's just that Modern Rails Opinions (whisper it) ain't what they were
@floppy yeah, I'm sorry, I appear to have Thrown The World at you there.
I re-read your first toot, and I think you'd be best served by `enhance`ing the `javascript:build` rake task with a single custom file task.
Something like this:
https://gist.github.com/rgarner/de784b58dee9f7745cdd3f3973b88643
@floppy what that will do is it will add `app/assets/builds/custom.js` to the prereqs for the `javascript:build` task, meaning when that task runs (as it always does at the start of the asset pipeline) your `file` task will be executed first if `app/assets/builds/custom.js` is not present.
@floppy but do consider scaling to a proper `esbuild.config.js` as per my previous Massive Gist; this stuff can only live in package.json for so long before the interdependencies get out of hand
@rgarner thank you mate, much appreciated! I will parse it at _some_ point. Fortunately my JS package is pretty simple at the moment.
@jaygooby @floppy propshaft is not quite ready. It works for simple cases but if you've got SASS files depending on other SASS files and you change a dependent, your CSS does not refresh in dev (and sometimes prod :( ). I consider it alpha software for this reason.
Likewise importmaps. I'm afraid the main file is a bit like combining Gemfile and Gemfile.lock. If you have anything beyond trivial dependencies it becomes unmanageable. Package managers are hard, and importmaps is a bit too simple.
@jaygooby I don't mean to use gist.github.com as a blogging platform, but I had to write this down about importmaps a year or two ago. I hope some of it is no longer true.
https://gist.github.com/rgarner/fcd16f1fe0043bad8b8c5d971412ff84