When to use stylesheet_pack_tag instead stylesheet_link_tag with Rails 6
Asked Answered
T

2

19

When creating a new rails project with Rails 6, it creates an application.html.erb with stylesheet_link_tag to load CSS and javascript_pack_tag for javascript files.

Now, rails 6 also provide a stylesheet_pack_tag, so my question is, when to use it? And if we use it, do we need to add all CSS files in app/javascript folder?

What is the best practice to load css, images with rails 6 and webpacker?

Theretofore answered 1/3, 2020 at 4:27 Comment(0)
T
31

You should use stylesheet_pack_tag if you are importing any CSS in Webpack AND if you have enabled extract_css: true for any environment in config/webpacker.yml.

Given the following directory structure:

app/
  javascript/
    packs/
      application.js
    styles/
      site.css

And the following code in application.js:

import '../styles/site.css'

You would use <%= stylesheet_pack_tag 'application' %> in your view, i.e., the name of the stylesheet matches the name of the "pack".

At this point, I also recommend renaming app/javascript to something like app/frontend. So, the key changes in config/webpacker.yml:

source_path: app/frontend
extract_css: true
app/
  frontend/
    packs/
      application.js
    styles/
      site.css
Tiertza answered 4/3, 2020 at 2:25 Comment(7)
Thank you @rossta, but what is the reasoning behind your answer: pack_tag vs link_tag?Akee
pack_tag is for Webpacker CSS. link_tag is for Sprockets CSS. You can choose one approach or use both; they are distinct bundlers.Tiertza
@rossta, you did mention "You would use <%= stylesheet_pack_tag 'application' %> in your view, i.e., the name of the stylesheet matches the name of the "pack"." But here "application" refers applicaition.js and there is not application.css or application.scss. So we need to manage CSS using js file only?Theretofore
That’s correct. In webpack, CSS and images are imported from your JavaScript files. Your Webpacker config will ensure they are output in the desired format.Tiertza
I didn't know it was required to have enabled extract_css...game changer @Tiertza :praying_hands:Noodle
I still get the Webpacker::Manifest::MissingEntryError when I take this approach. Anyone else get that when using the stylesheet_pack_tag and solve it?Insane
My god... I spent a couple of hours debugging why my .scss files were not loading. Thank you @rossta!Mckinley
L
2

Just to try to clarify this a little. This is based on my current understanding, which seems to work well enough but still might not be fully accurate.

CSS processed by the asset pipeline gets a css_link_tag and css that is imported via a Webpacker javascript bundle is referenced with css_pack_tag.

Asset pipeline css is in app/assets/stylesheets. Webpack css is in app/javascripts/wherever_you_want.

So in webpack, all of the css imported into a javascript bundle is eventually extracted to a servable file that can be referenced via the same name as the js bundle.

So if in app/javascripts/application.js you have:

import 'app/javascripts/css/one.css'
import 'app/javascripts/css/two.css'
import 'app/javascripts/css/three.css'

These will be referenced with

css_pack_tag 'application'

This comes out looking like this in my deploy logs

Entrypoints:
  application (430 KiB)
      css/application-9d82d487.css
      js/application-9f45d7ff735a7a203f28.js

It also bears noting, as was mentioned above that this behavior is affected by the extract_css setting.

Presumably this is false in development by default and true in production. One big GOTCHA with this is that, at least in my case, the css_pack_tag wasn't actually "required" in development, in the sense that removing it had no effect because it wasn't extracted locally. It still "worked" because the css was loaded in the javascript and seemed to be applied somehow that way. So I removed these tags thinking they were unnecessary before my understanding improved. Unfortunately when I deployed to production on heroku some time later, none of my css was working and it took me a while to figure out why and remember that I had removed these css_pack_tag lines.

Lawler answered 6/12, 2020 at 6:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.