Error compiling CSS asset (Compass + Sass + Heroku) - ruby-on-rails

I have a site running on Heroku using Compass with Saas an is working fine (compiling assets when pushing to Heroku seems to be fine).
I added a new folder inside assets to namespace other styling, like this
/app/assets/stylesheets/site/site1.css
/app/assets/stylesheets/site/site2.css
/app/assets/stylesheets/site/common/base.css.saas
/app/assets/stylesheets/site/site/site1.css.saas
/app/assets/stylesheets/site/site/site2.css.saas
...
The problem is when I visit a page that use site1.css styling I get the following error
Error compiling CSS asset
Sass::SyntaxError: File to import not found or unreadable: ../compass/css3/text-shadow.
Load path: /app
(in /app/app/assets/stylesheets/site/common/base.css.sass)
/app/app/assets/stylesheets/site/common/base.css.sass)
The line that the error refers is this
/app/assets/stylesheets/site/common/base.css.sass
#import "../compass/css3/text-shadow"
I tried both "../compass/css3/text-shadow" and "compass/css3/text-shadow". In both cases I got the same error.
Any idea how to solve this?

Solved.
I needed to specify on production.rb file the additional files to compile
config.assets.precompile +=
Dir["#{Rails.root}/app/assets/stylesheets/site/site/*.*"].collect {|s| "site/" + File.basename(s).gsub(/.scss|.sass/, '') }
Now is working fine.

Related

Image Asset Not Loading In Production

I'm running Rails 5.2.2. I recently separated some admin code from my frontend and in the process moved my controllers, views, css & JS to folders in either frontend or admin respectively.
In development, everything works fine. In production, I am unable to load image assets from my css.scss files using the following line background: url(arrow.png) no-repeat left center; (located in app/assets/stylesheets/frontend/application.css.scss).
My assets has the following file structure:
assets/
config/
images/
admin/
frontend/
products/
another_folder/
javascripts/
admin/
frontend/
stylesheets/
admin/
frontend/
I did not have to change any of my image tags in my views once I made these changes for my images in assets/images/products so I figured that I wouldn't have to do that anywhere else either; things just seemed to work. However, in production the arrow.png returns a 404. When I inspect the image request, the link to the image is /assets/frontend/arrow.png. I use the RAILS_ENV=production flag when compiling assets. I have also run rake assets:clobber with the production flag then tried compiling the assets again. I've deleted all browsing data.
Here are my server logs where the image is requested:
I, [2019-08-01T05:06:22.496953 #6733] INFO -- : [8a0b82c0-c4a3-419f-92fd-8f4a89bbe643] Started GET "/assets/frontend/arrow.png" for 35.188.197.210 at 2019-08-01 05:06:22 +0000
F, [2019-08-01T05:06:22.501395 #6733] FATAL -- : [8a0b82c0-c4a3-419f-92fd-8f4a89bbe643]
F, [2019-08-01T05:06:22.503739 #6733] FATAL -- : [8a0b82c0-c4a3-419f-92fd-8f4a89bbe643] ActionController::RoutingError (No route matches [GET] "/assets/frontend/arrow.png"):
UPDATE:
Adding this to a view works fine in production so I can confirm the asset does indeed compile properly.
<%= image_tag("frontend/arrow.png") %>
For Rails 5, please try to change following configuration:
config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?
to
config.public_file_server.enabled = true
OR
you can set RAILS_SERVE_STATIC_FILES true in your passenger_env_var. That will also work.
Helo is this code works for you?
background: image-url(arrow.png) no-repeat left center;

Webpacker with Rails compiles scss partials

I have created a sample app at https://github.com/joostvanrijn/webpacker to be complete, but here's my issue:
# app/javascript/packs/stylesheets.scss
#import 'variables';
#import 'foo';
# app/javascript/packs/_variables.scss
$bar: #fff;
# app/javascript/packs/_foo.scss
body {
color: $bar;
}
Now when I run /bin/webpack-dev-server I get
Undefined variable: "$bar".
And more importantly
[84] ./app/javascript/packs/_foo.scss 988 bytes {2} [built] [failed] [1 error]
It seems as if Rails/webpacker compiles all files instead of just stylesheets.scss
I've been able to find the answer eventually.
From the Webpacker readme:
The configuration for what Webpack is supposed to compile by default
rests on the convention that every file in app/javascript/packs/*
(default) or whatever path you set for source_entry_path in the
webpacker.yml configuration is turned into their own output files (or
entry points, as Webpack calls it).
So by moving the sass partials to another folder now only the stylesheets.scss gets compiled.

Sass import from rails engine not working

I've created a Rails Engine for assets. I don't use sprockets for css. Instead, I rely on sass's #import. This works perfectly fine in the test/dummy app, but in the Rails app that is requiring the engine, it keeps throwing
Sass::SyntaxError: File to import not found or unreadable: gumby.
I've been at this for a while, and originally the path wasn't in the load path for sass. But then I added
config.sass.load_paths << "#{Gem.loaded_specs['gumby_on_rails'].full_gem_path}/app/assets/stylesheets"
to my config/application.rb and now it definitely shows the correct path to the file I'm trying to import. It is the second to the last path listed in the following trace:
Sass::SyntaxError: File to import not found or unreadable: gumby.
Load paths:
CompassRails::SpriteImporter
CompassRails::SpriteImporter
CompassRails::SpriteImporter
CompassRails::SpriteImporter
CompassRails::SpriteImporter
CompassRails::SpriteImporter
CompassRails::SpriteImporter
CompassRails::SpriteImporter
CompassRails::SpriteImporter
/Users/brandon/code/personal/blog_update/app/assets/images
/Users/brandon/code/personal/blog_update/app/assets/javascripts
/Users/brandon/code/personal/blog_update/app/assets/stylesheets
/Users/brandon/code/personal/blog_update/vendor/assets/javascripts
/Users/brandon/code/personal/blog_update/vendor/assets/stylesheets
/Users/brandon/.rvm/gems/jruby-1.7.11#blog/gems/angularjs-rails-1.0.7/vendor/assets/javascripts
/Users/brandon/.rvm/gems/jruby-1.7.11#blog/gems/turbolinks-2.2.2/lib/assets/javascripts
/Users/brandon/.rvm/gems/jruby-1.7.11#blog/gems/jquery-rails-3.1.0/vendor/assets/javascripts
/Users/brandon/.rvm/gems/jruby-1.7.11#blog/gems/coffee-rails-4.0.1/lib/assets/javascripts
/Users/brandon/code/personal/gumby/app/assets/stylesheets
/Users/brandon/code/personal/blog_update/app/assets/stylesheets
The rails engine's tree looks like this
app/
assets/
stylesheets/
gumby/
...
gumby.css.scss
(I know that technically you should namespace all your assets in an engine, but I didn't want to have gumby/gumby, and I feel the chances of a name clash are slim.)
So in the test/dummy app I can import this file via #import 'gumby';, but this fails in the Rails app. With the above exception. How do I get this working?
And by the way, this is a Rails 4.1 app, and the answers to several other "similar" questions are all due to using groups in the Gemfile. Rails 4 got rid of groups so this is not the problem/solution.
So the solution for me was to suck it up and namespace it gumby/gumby. Then I also had to change the config/application.rb to:
config.assets.paths << "#{Gem.loaded_specs['gumby_on_rails'].full_gem_path}/app/assets/stylesheets"
And for some reason modular-scale wasn't being required properly, even though the engine already required it. So I had to change application.css.scss to application.css.scss.erb and put <% require 'modular-scale' %> at the top.
then you should write it like this :
config.sass.load_paths << "#{Gem.loaded_specs['gumby_on_rails'].full_gem_path}/app/assets/stylesheets/gumby"
or try this (untested)
#import_tree 'gumby';

How to precompile assets and avoid "Error: file isn't precompiled" on specific pages?

When I push my code to Heroku I get the following message:
Precompiling assets failed, enabling runtime asset compilation
Runtime compilation can cause issues, so I added the following line to config/application.rb:
config.assets.initialize_on_precompile = false
(As suggested at Error pushing to heroku - aborting my rake assets:precompile and on Heroku Help )
This allows the precompilation to work. However, some of my pages include other javascript files. For example, I include a file from 'vendor/javascripts' within certain pages by putting a tag on the specific page:
<%= javascript_include_tag "src/ace.js" %>
When I visit such a page, it causes the following error (when precompiling works):
ActionView::Template::Error: src/ace.js isn't precompiled
How can I fix it so such pages do not throw errors?
You'll need to add the file to the assets.precompile.
Add the following to your config/environments/production.rb to compile all your css/js files:
config.assets.precompile = ['*.js', '*.css']
You can add your ace.js and other required files in a javascript file for instance "custom.js"
Then you can use your regular code to include the file
Add the following in custom.js. ( Assumed ace.js resides in vendor/javascripts)
//= require ace
Add the file to compilation list by adding following in application.rb
config.assets.precompile += %w( custom.js )
You can now use your javascript_tag to include the source
<%= javascript_include_tag "custom" %>

Precompile rails AngularJS assets

I am trying to compile my Rails app assets using RAILS_ENV=production bundle exec rake assets:precompile, but this doesn't compile my AngularJS assets, so my console report this:
ActionController::RoutingError (No route matches [GET] "/assets/app/views/products/index.html"):
My AngularJS assets are under "/assets/app/", so I tried to compile the angular folders by adding following into my production.rb but still not working.
config.assets.precompile += %w(app/* bootstrap/* datatable/* ....
I can find the compiled index file under this path:
public/assets/app/views/products/index-2429bd0f8fc0762dcc075e51f0306c5b.html
Any idea?
UPDATE
Also tried config.serve_static_assets = false in production, but it cause more missing assets errors
Thanks
I've worked through this in my app by using constants to get the path structure right.
my angular app is journey (yours would obviously be different)
so I declare the angular app as a module
this.journey = angular.module('journey', [
'ngResource',
'ngRoute'
]);
Then I have a file called constants.js.erb where I declare my templates
journey.constant('INDEX_TEMPLATE', '<%= asset_path('journeys/journey_index.html')%>');
journey.constant('EDIT_JOURNEY_TEMPLATE', '<%= asset_path('journeys/journey_edit.html') %>');
Finally in my services I use the constants declared as the template url
journey.config([
'$routeProvider',
'$locationProvider',
'INDEX_TEMPLATE',
'EDIT_JOURNEY_TEMPLATE',
function ($routeProvider, $locationProvider, INDEX_TEMPLATE, EDIT_JOURNEY_TEMPLATE) {
$locationProvider.html5Mode(false);
return $routeProvider.when('/', {
templateUrl: INDEX_TEMPLATE,
controller: 'JourneyIndexController'
})
}
])
This way I don't have to worry about where the files are or how rails is organising the routing.
Hope this helps

Resources