rails icon indicating copy to clipboard operation
rails copied to clipboard

Update the Asset Pipeline Guide [skip ci]

Open brenogazzola opened this issue 1 year ago • 2 comments

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:

  1. There are two ways to do JavaScript in Rails 7: Bundling and import maps
  2. Import maps is the default. Here's how that works.
  3. It has these caveats, if those are relevant to you, go with bundling.
  4. Both approaches lean on an asset processor.
  5. The default one is Sprockets. It'll work out of the box like this.
  6. But side note, we're working on a replacement for Rails 8+ called Propshaft, and if you can live with [caveats].
  7. 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.

brenogazzola avatar Jun 19 '22 14:06 brenogazzola

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?

bradgessler avatar Jun 21 '22 18:06 bradgessler

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.

brenogazzola avatar Jun 24 '22 00:06 brenogazzola