Home > Back-end >  Idiomatic Sass processing in Rails 7
Idiomatic Sass processing in Rails 7

Time:02-25

I'm confused about the idiomatic way to process Sass in Rails 7.

The README.md for the importmap-rails repo says:

This frees you from needing Webpack, Yarn, npm, or any other part of the JavaScript toolchain. All you need is the asset pipeline that's already included in Rails.

and The Rails Guide to The Asset Pipeline states that:

Rails can easily work with Sass by adding the sassc-rails gem to your Gemfile, which is used by Sprockets for Sass compilation

But in October 2020 we learned that LibSass is Deprecated, and that we should be using Dart Sass instead.

The sassc-rails gem is based on LibSass.

Hence should we be using something else to process Sass? And if so is the documentation on the Rails 7 asset pipeline misleading?

I'm relatively new to Rails and my naive reading of The README.md and The Asset Pipeline Guide led me to think that we should be using "the asset pipeline that's already included in Rails" to compile Sass and did not need "Yarn, npm, or any other part of the JavaScript toolchain".

What is the Rails 7 idiomatic way to process Sass?

CodePudding user response:

(Copied directly from DHH's reply to the GitHub Issue.)

There are two ways to use Dart Sass in Rails. Either through cssbundling-rails with Node. Or with https://github.com/rails/dartsass-rails, using the standalone Dart Sass compiler, without node. If you're doing a default Rails 7 app that uses import maps, you should do the latter.

We need to update the asset pipeline guide and other documentation to recognize this.

CodePudding user response:

In addition to the answer pasted in by @dumbledad, note that there is a serious disconnect in Rails 7 between JavaScript and CSS. While import maps as a specification and concept can in theory handle both ECMAScript modules and CSS modules, Rails 7 only supports ECMAScript modules and you're left out in the cold with CSS.

TL;DR, import maps are almost useless if you have any third party components that comprise CSS as well as JS components, unless you don't mind manually version-maintaining the same thing via two different package management systems in two different parts of your application. If you're happy with that dual maintenance overhead, then you can keep it lightweight and use import maps along with e.g. dartsass-rails.

See later comments on https://github.com/rails/importmap-rails/issues/107 for an official reply - basically, use jsbundling-rails and cssbundling-rails with a fully Node-based setup if you're going to have any components with both JS and CSS parts, unless you want to version-manage them separately.

  • You'd remove any gem that gave you those components, e.g. remove Bootstrap
  • You'd instead manage such dependencies via package.json and Yarn
  • You'll use bin/dev to run your development server and have CSS & JS compilation

While this much heavier approach is sad compared to either a simple Gem Sprockets workflow (non-Webpacker) or import maps, and while it seems to have significant drawbacks now that e.g. @import wildcards aren't supported so you have to now hand-maintain lists of files that previously could just be linked as a tree - and so-on, there are sadly a lot of drawbacks compared to e.g. Rails 4-5 ish era simple Sprockets and gems with synchronous on-demand compilation by a single server process in development - it does mean you have access to a dramatically wider range of options for preprocessing, transpilation, generalised NPM / Yarn ecosystem or alternate build mechanisms, and it's now fronted by "vanilla" Yarn and package.json without any weird gems in the middle making things harder to learn.

  • Related