-
Notifications
You must be signed in to change notification settings - Fork 45
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Migration from sassc-rails
workarounds
#43
Comments
Thanks for this—I was especially relieved to see that globs simply don't work (and it's not something I screwed up). I think migration guide and/or utilities would be awesome. |
@nevans Thank you so much for this! Your explanation really helped me to understand. I was having trouble with an old version of the |
Can someone explain why globs are not working anymore? its really hard to upgrade and I dont understand why the old gem was deprecated, when the new gem doesn't fulfill many features which were used before. What is the recommeded way to migrate f.e. the rails-jquery-ui gem? |
Won't this be interpreted as a "plain CSS import"?
https://sass-lang.com/documentation/at-rules/import/#importing-css I'm trying to work out an issue where this results in a plain CSS import: @import "accessible-autocomplete/dist/accessible-autocomplete.min.css"; ...while this works fine locally, but fails when building on Heroku: @import "accessible-autocomplete/dist/accessible-autocomplete.min";
|
OK, turns out My issue was resolved by adding a nodejs buildpack before the Ruby buildpack (I don't know why this is required). |
Yes, you're right. Sorry about that. As you noticed, it should be fine if you simply drop the ".css" extension from the import. In my app, I have several css files that are successfully imported from
I haven't used heroku in a long time, but I'm guessing that, without the nodejs buildpack, it doesn't actually install the node packages into the node_modules directory. |
@nevans thanks so much for the response. I think it turned out to be something much more subtle: I'm using jsbundling-rails and dartsass-rails, and both of them inject a build step as prerequisite of The issue is that the ordering of these builds isn't explicitly defined - I guess it might be based on the order that the gems are listed in the In my setup, Adding the Node buildpack to run before the Ruby buildpack has the effect of installing dependencies first, so that they're available when dartsass runs, with the downside that jsbundling will build everything again (unless we configure it not to). I'm not sure what either of these gems could do to ensure that they're run in the correct order 🤔. |
To be clear: I don't think this is a Heroku problem: I think in any build environment with both
|
@dgmstuart Ah, I see. That makes sense. I didn't actually think about
...
If I remember correctly, But we can add our own deps to existing tasks if we want it to work reliably. Since you're using task "dartsass:build" => "javascript:install" With that, you should (probably) be able to rely on rake to ensure that the JS deps are only installed once and your JS is only built once. |
This worked! Thanks so much 🙏 dgmstuart/swing-out-london#276 It's hard to tell, but it does indeed look like this only results in the JS being installed once. |
I'm still struggling with this - I have font-awesome and active_scaffold both misbehaving due to scss.erb usage ... but an added wrinkle is that in my own scss files I have an |
Hi @dgm - could you be more specific? What is failing, where and with what error/behaviour? Looks like the old way of including font-awesome was this?
...so I guess this has become |
Yes, I have to use I was able to get things working using the dartsass-sprockets gem instead. |
We're still using Rails Sprockets and we didn't want to run # config/initializers/assets.rb
Rails.application.config.assets.configure do |env|
env.prepend_path(Rails.root.join('app/assets/builds'))
end The reason for this hook is that Sprockets loads the assets paths before dartsass-rails compiles the CSS. Therefore, when it runs the first time, it won't find CSS in the |
It would help enormously if we had better documentation on the incompatibilities with
sassc-rails
and known workarounds for them. I'm willing to create aREADME.md
ordocs/migrating.md
PR, but I'd need guidance (and I can't promise when I'll get around to creating it).Following are my initial thoughts start towards what might be needed in a
docs/migrating.md
, and the workarounds that I used. 🙂 You can maybe consider it a "rough draft". I would appreciate advice on my workarounds: Can they be simplified or improved? Are they factually inaccurate (I did test them all, but there might be something abnormal in my testing env)? Which ones deserve to be included in a documentation PR? What am I missing?Glob imports
Imports need to be explicitly enumerated. A simple pattern is to convert all
@import "foo/**/*";
glob imports into@import "foo";
and add a newfoo/_index.scss
file which contains explicit imports for all of the globbed files. Iffoo/_index.scss
already exists,@import "foo/glob";
andfoo/_glob.scss
could be used instead.This can be tedious and error-prone to do by hand, so it would be nice to add a
find|awk
bash one-liner to the documentation. Even nicer would be adartsass:migrate-globs
task.Require directives
Although
sass-rails
andsassc-rails
both process the sprocketsrequire
directives in.scss
files,dartsass-rails
does not. I found several different workarounds for this. The first two should work withsprockets
orpropshaft
, but the others requiresprockets
.Convert to
@import
Fortunately,
dartsass-rails
adds all gem asset paths as load paths fordartsass
. So, if the gem is only using basic css or scss, we can generally replace//= require "foo"
with@import "foo";
Unfortunately, when the gems themselves rely on sprockets features, this won't work. For example:
jquery-ui-rails
uses sprocketsrequire
directives. Andfont-awesome-rails
uses erb to process a.css.erb
file. Other gems may have other incompatibilities.Convert to node packages
In many cases, a node package exists for the library in question. In that case, the simplest approach may be to convert from the bundled gems to the node package. The
@import
statement may need to use the full path to the stylesheet, relative tonode_modules
. E.g://= require "jquery-ui"
might be converted to@import 'jquery-ui/dist/themes/base/jquery-ui.min';
. Alternatively, the path to the node package'sdist
directory could be added toconfig.assets.paths
.However, in some cases, the node packages require non-trivial changes to the application code, or the gems are significantly simpler to use, or the gems come with additional functionality such as image assets and helper modules. In those cases, the next two workarounds will probably work.
Use a sprockets css entrypoint to require dartsass build output
Add a prefix or suffix to the entrypoint with the problematic
require
directives. Add this new file to theconfig.dartsass.builds
hash. Remove the sprockets requires from the top, to avoid confusion (optional, they are comments so they're simply ignored).Create a new
.css
file with the same base name as the original entrypoint (only changing the extension from.scss
to.css
). Add this file to eitherconfig.assets.precompile
ormanifest.js
. Copy all of the originalrequire
directives into this file (nothing else). Add arequire
directive for the renamed.scss
file at the bottom of this css file--or ifrequire self
was used, replace that. Once dartsass has run and written toapp/assets/builds
, the new sprockets entrypoint should be able to work just like before.Use new entrypoints and new
stylesheet_link_tags
Convert the
= require
that work into@import
. The problematic imports can mostly be discovered by simply converting them all and then commenting out the ones that don't work untildartsass:build
runs without errors.config.assets.precompile
. Sprockets precompiles these entrypoints using the asset paths and manifests of all loaded rails engines (gems).stylesheet_link_tag
for the existing entrypoint, add astylesheet_link_tag
for each of these new entrypoints.Examples
The examples are based on the following hypothetical broken scss:
Use a sprockets css entrypoint to require dartsass build output
The example could be converted to something like the following:
The erb would be unchanged.
Use new entrypoints and new
stylesheet_link_tags
The example would be converted to something like the following:
The text was updated successfully, but these errors were encountered: