rails
rails copied to clipboard
Update the Asset Pipeline Guide [skip ci]
Intro
Rails 7 brought with it an overhaul of the Asset Pipeline in the form of multiple new gems that either introduced a new way of handling assets (importmaps-rails), or broke down existing gems (propshaft, jsbundling-rails, cssbundling-rails) into smaller parts that make use of existing standalone tools and therefore support modern features that were previously unavailable.
Now that things are a bit more stable and developers are already upgrading (and getting confused due to amount of options), it's time to update the rails guides.
How should we go about this?
Got some feedback and guidance from the core devs on my original guide, so here's the basics...
Primary Guidelines:
- Provide a single default path and explain it all the way. That's import-maps.
- Avoid at all costs option proliferation. Do not give devs a bunch of options and let then figure it out.
Secondary Guidelines:
- Focus on relevant options for Rails 7+;
- Relegate legacy options (like webpacker) to footnotes that link elsewhere;
- Default 1: Import maps + Sprockets
- Default 2: Bundling + Sprockets
- Future Default: Propshaft
- Legacy Default: Webpacker
Proposed structure:
- There are two ways to do JavaScript in Rails 7: Bundling and import maps
- Import maps is the default. Here's how that works.
- It has these caveats, if those are relevant to you, go with bundling.
- Both approaches lean on an asset processor.
- The default one is Sprockets. It'll work out of the box like this.
- But side note, we're working on a replacement for Rails 8+ called Propshaft, and if you can live with [caveats].
- Here's how Propshaft works.
Todo
- [ ] Rewrite the base guide
- [ ] Update the Sprockets guide
- [ ] Update the Webpacker guide
- [ ]
If you’d like to help
For this PR, make changes, open a PR. Or post suggestions here. Or join us in the asset pipeline channel in discord.
I asked a few questions in Discord that I'm distilling into some notes here.
Sweeping generalization
I was throwing a few things out there to distill what pipelines should look like, which landed at:
For the default/basic asset usecase:
Rails 7: Import Maps + Sprockets
Rails 8: Import Maps + Propshaft
If you need advanced javascript tooling:
Rails 7: jsbundling + Sprockets
Rails 8: jsbundling + Propshaft
"Advanced" didn't make much sense to me, so I did some more digging. Turns out "advanced" means "you need to use yarn and/or node to manage JS & CSS dependencies".
What's the difference between cssbundling-rails
, jsbundling-rails
, dartsass-rails
, etc?
After a few more questions, I learned that cssbundling-rails
and jsbunding-rails
gems all wrap yarn
to manage dependencies. That wasn't obvious to me before, but now it is after asking a few questions.
I also asked "when would I use dartsass-rails
vs the dart
option for cssbundling-rails
?". Again, it came back to whether or not I needed to use node/yarn to manage dependencies.
What's the overarching goal of future Rails asset pipelines?
If I had to distill it into as few words as possible, Rails wants to ship without node
or yard
as a dependency. Instead it will opt for importmaps
, which requires no compilation, and propshaft.
That said, there are more complex use-cases for front-end developers where they may need to use npm or yarn to manage front-end dependencies. In that case, cssbundling-rails
and jsbundling-rails
would be the recommended path forward.
Upgrade path from the basic to advanced use case
A point I made is that switching from the basic asset management use cases to the more complex requires a lot of changes to configuration files, location of asset files, etc. How might this migration be made less complex? Location of assets, tooling, documentation, etc. could all help.
Propshaft inconsistency
One inconsistency with the stated approach between *bundling-gems
, propshaft
and the goal of eliminating Node/Yarn as a dependency for the simple Rails 8 use case is propshaft
currently requires the bundling gems: https://github.com/rails/propshaft/blob/main/UPGRADING.md
Will propshaft
depend on the bundling gems in the future? Or is it a goal to remove those as the code matures out of alpha?
About Propshaft, the upgrade guide was written for apps running the sprockets/webpacker combo. This is why it goes full node/yarn tooling and mentions the bundling gems (jsbundling and cssbundling)
But Propshaft by itself does not require them. It only does fingerprint, so if you pair it with importmaps and tailwind or a BYO css library, neither are required.