Rails - sprockets cannot recognize scss files - css

I recently upgraded my Sprockets from 3.7.2 to 4.0.2 and since then my application.css file cannot recognize one of the files that has been written in scss:
*= require editor/content-tools.scss
*=/ require_tree .
*=/ require_self
*/
(editor/content-tools.scss is located in vendor, not in app/assets).
While I try to execute it I receive this error:
ActionView::Template::Error (couldn't find file 'editor/content-tools.scss' with type 'text/css'
Sprockets is looking for a 'text/css' type file and if I rename my file to content-tools.css it stop producing errors, which eliminates possible problems related to path findings.
So my question is how can I tell sprockets to check look for files with .scss extensions in my application.css as it did before?

From sass-rails
Sprockets provides some directives that are placed inside of comments called require, require_tree, and require_self. DO NOT USE THEM IN YOUR SASS/SCSS FILES. They are very primitive and do not work well with Sass files. Instead, use Sass's native #import directive which sass-rails has customized to integrate with the conventions of your Rails projects.
So you could achieve that by:
Rename application.css to application.scss
Use import syntax instead of require:
// application.scss
#import "editor/content-tools.scss";
#import "*";

Related

Tailwind + SASSC in conjunction with Sprockets

I am having issues with Tailwind.
Seems like Tailwind is not compatible with SASSC as it probably uses newer CSS. https://github.com/rails/cssbundling-rails#how-do-i-avoid-sasscsyntaxerror-exceptions-on-existing-projects
Though I really need SASSC for the asset_path helpers in order to resolve custom fonts fingerprinted resources names that Tailwind will use.
I have been thinking of doing :
Keep SASSC and removing tailwind.css file from the Rails 7 pipeline by having CSSbundling exporting it directly in the public folder. Though asset is not fingerprinted then I can't really add a cache policy to the file which is a shame.
Try to remove asset_path from the SASS files and replacing it with .erb files to resolve the name of the fingeprinted asset. But probably won't work as the erb preprocessing should happen before precompilation.. (EDIt: seems to work but need to find out is it is using the current asset path or an older asset path)
Put fonts in public folder and call from there. Fonts are not assets that are designed to be changed for their respective file names. So I guess this is the best solution..
Has anyone found a solution for this ?
EDIt :
Seems like gem sassc-rails is really lagging on the Sass versions https://www.npmjs.com/package/sass as last repo update is 3 years old. Has someone tried to use the sass package with Jsbundling in order to remove the sass processor from asset pipeline ?
We could then remove the stylesheets folder from the app/config/manifest and leave sprockets to compile the Sass processed files from builds ?

Rails: Precompiled assets missing node modules

I am using yarn with my rails 5.1 app (not webpacker, just the default asset pipeline).
Running a local server in development environment, I experience no issues with my assets.
But as soon as I precompile my assets (the environment doesn't matter) or let Heroku package my assets, all stylesheets (of node modules) I imported from within my application.sass file don't work anymore.
The reason for that behavior is that sass compiles all files into one output file, but because of some reason appears to miss the #import statements which include node modules and load these files separately.
So this:
#import "components/index.sass"
#import "nodemodule/nodemodule.css"
Compiles to this in development:
// content of "components/index.sass"
// content of "nodemodule/nodemodule.css"
and to this in production:
// content of "components/index.sass"
#import "nodemodule/nodemodule.css"
while loading node_module/nodemodule.css separately as an asset, but the browser cannot resolve it. Javascript works fine.
The links are from my project that you can use as reference
in your asset.rb you need to include the /node_modules path in your default load_path.
If you open the rails console and input Rails.application.config.assets.paths you should see the new path /yourproject/node_modules added.
Then you simply write:
#import "nodemodule.css"
In my case for bootstrap 4 in my application.scss
#import bootstrap/scss/bootstrap
which correspond to the file in node_modules/bootstrap/scss/bootstrap.scss
for jquery.js and bootstrap.js you can check my application.js
I was having the same problem. Inspired by this comment removing file extensions from the imports ended up fixing it.
This didn't work:
#import "#shopify/polaris/styles.css";
#import "#uppy/core/dist/style.css";
#import "#uppy/dashboard/dist/style.css";
while this did:
#import "#shopify/polaris/styles";
#import "#uppy/core/dist/style";
#import "#uppy/dashboard/dist/style";
The node_modules need to be installed with npm install for example, so they're probably not getting installed on Heroku. Check out https://devcenter.heroku.com/articles/using-multiple-buildpacks-for-an-app
Most likely, you need to setup a Node.js buildpack which will install your npm dependencies.
I have finally found the problem. It is a very nasty bug of the sass-rails gem & an unfortunate design of the sprockets component of Rails.
1) sass-rails
#import does not seem to work with node_modules as it does with other assets. While those other assets get compiled into one file, node_modules only get referenced, loaded by the browser as separate sources, but ultimately not being used by the browser.
2) sprockets
Sprockets' require statement does only work if it is at the beginning of a file. Or as they put it in their documentation:
Note: Directives are only processed if they come before any application code. Once you have a line that does not include a comment or whitespace then Sprockets will stop looking for directives. If you use a directive outside of the "header" of the document it will not do anything, and won't raise any errors.
However, in my case, I was importing directives from a file that itself was imported from application.sass.

Rails 4 + bower-rails gem + bower + bootstrap sass

I have installed bower-rails gem
then in bower file I included bootstrap-sass, it installed bootstrap-sass in vendor/assets/bower_components.
Now according to a resource bower-rails automatically takes care of adding bower_components to assets, so I am trying this in application.css
*= require_tree .
*= require_self
*= require 'bootstrap-sass'
*/
But it throws me error that bootstrap-sass file not found.
Do I have to manually add vendor/assets/bower_components to assets?
I am pretty new to rails so some explanation would help a lot.
I am following this resource
EDIT:
On doing rails c and printing Rails.application.config.assets.paths
I can see vendor/assets/bower_components in asset paths
`
Finally I resolved the issue by removing all the bower components and running
rails g bower_rails:initialize
It created an intializer for assets bower_rails.rb, which finally solved the problem

Rails + Bower issue with assets path

I have install "Tinymce" though bower into my rails app in vendor/assets/bower_components/tynymce-dist
I include js assets in application.js and it works ok
//= require tinymce-dist
then I include css files in application.css
#import 'tinymce-dist/skins/lightgray/skin.min.css'
it works, but I have an error in rails console
ActionController::RoutingError (No route matches [GET] "/assets/skins/lightgray/skin.min.css"):
and in chrome console
GET http://localhost:3000/assets/skins/lightgray/skin.min.css
it calls from tinymce script in that way
skinUrl = tinymce.baseURL + '/skins/' + skin;
looks like it calls absolut url.
One solucion is to use Tinymce gem, but I dont want to use this way.
How to fix this problem.
If you're using Bower in your Rails app, you'll do well looking into Rails Assets:
This basically allows you to include bower-enabled assets as gems. You just have to search for the respective gem on their app, and then add the gem to your Gemfile:
RA actually have TinyMCE-dist already:
I would personally recommend using Rails Assets - I can delete the answer if you'd rather not. It will give you the benefits of bower and the dependability of the gem system:
#Gemfile
source https://rubygems.org
source https://rails-assets.org #-> add this line
gem 'rails-assets-tinymce-dist'
Then add the following to your JS & CSS assets:
#app/assets/javascripts/application.js
//= require tinymce-dist/tinymce.js
#app/assets/stylesheets/application.css
#import 'tinymce-dist/skins/lightgray/skin'

Require Compass plugins (Gems) in Rails 3.2.X

I'm fairly new to Rails but I use sass/compass everyday in non-Rails projects.
I want to use compass plugin gems (e.g. compass-rgbapng) along with compass in the project (Rails 3.2.4). I'm using compass-rails too with gem 'sass-rails ~> 3.2.6' and gem 'sass ~> 3.2.7'.
I added both gems to the Gemfile in the :assets group. I bundle installed, etc. I use the #import call in my sass files to use the gems.
Here is what I get from the server :
File to import not found or unreadable: rgbapng.
Load paths:
Sass::Rails::Importer(/Users/simonwalsh/src/quarterly/app/assets/stylesheets/store/_base.sass)
/Users/simonwalsh/src/quarterly/app/assets/stylesheets
/Users/simonwalsh/src/quarterly/.bundle/ruby/1.9.1/gems/compass->0.12.2/frameworks/blueprint/stylesheets
/Users/simonwalsh/src/quarterly/.bundle/ruby/1.9.1/gems/compass->0.12.2/frameworks/compass/stylesheets
/Users/simonwalsh/src/quarterly/.bundle/ruby/1.9.1/gems/breakpoint-2.0.7/stylesheets
Compass::SpriteImporter
(in /Users/simonwalsh/src/quarterly/app/assets/stylesheets/store/_base.sass)
I did not require the gem anywhere as it is not supposed to be required. Even then, I don't even have a compass.rb or any other config files...
--- EDIT ---
I went to compass-rails doc to try their way of doing that. Here is what I tried :
I added a compass.rb in the initializer with either require 'rgbapng' or config.compass.require 'rgbapng' in it,
I tried the same as above in the application.rb file.
Still nothing works, the app refuses to comply with my #import rgbapng call...

Resources