Rails 3.1 introduces a new way of organizing both JS and CSS with the introduction of manifest files. For example, application.js might look like this:
//= require jquery
//= require jquery-ui
//= require jquery_ujs
//= require_tree .
This will grab various bits of Jquery, all of your own JS, concatenate them together and serve it as a single file to clients. Simple enough.
Unfortunately the picture is not so clear to me with SASS. SASS already has concatenation built in using #import.
Should I change all of my partials into full SASS files and then concatenate them using the manifest file or continue using #import? Why?
Sprockets converts all imports to CSS before concatenating, so it can't be used to share mixins and variables across files. I'm guessing this is going to stay that way just because you can import SASS, LESS and CSS files via that method.
So here's how I do it:
If I have ERB to include (mostly for asset_path() calls), I put them in my main file, application.css.scss.erb
If I have vendored CSS I want to include, I require it via Sprockets, e.g. //=require jquerymobile
In that same file, I use the SASS #import command to explicitly load all files. None of the #import'ed files may be .erb though.
load the basic stuff (e.g. reset) and imports with mixins
declare variables
import the specific styles
Here's how my app.css looks at the moment. Don't forget the ";" and the quotes:
// Using SASS import is required for variables and mixins to carry over between files.
#import "reset.css.scss";
#import "mixins.css.scss";
$color_base: #9b2d31;
$color_background: #c64e21;
// Using asset_path is important for browsers to use versioned url for the asset.
// This lets us do aggressive caching.
$logo-url: url(<%= asset_path("logo.png") %>);
#import "application/layout.css.scss";
#import "application/sidebar.css.scss";
#import "application/videos.css.scss";
#import "application/pages.css.scss";
...
Note that I'm still exploring the Rails 3.1 asset pipeline, so your mileage may vary. I'll try to come back & update if I find anything else interesting.
The best way to solve this is to use the native #import directive as explained here: https://github.com/rails/sass-rails#important-note
This question was already answered here : how to use sprockets imports with sass
Hope this helps! :)
The sass-rails gem explicitly states not use the require syntax with SASS files - use SASS's #import statements instead.
Related
Can I import all .scss files in a sub-directories with node-sass?
I'm guessing it would be something like this?
#import './directory/**/*.scss'
No, there is a request on the Ruby Sass GitHub repository for this functionality, but libsass/node-sass won't implement functionality not in the main language. You may be able to find plugins that do this.
The asset_pipeline guide mentions the use of require_tree for JavaScript and style-sheet files to recursively load every file of the respective files types, but doesn't mention any advantages or disadvantages of doing so. For instance are there any benefits to me having require_tree in my application.js file? In one case it prevents me from manually having to include individual javascript files for various pages. On the other hand theres been many occasions where I forget that I'm using the require_tree directive and accidentally loading libraries more than once.
Are there any performance-related issues involved in loading javascript/stylesheet files for pages that don't even make use of them (as would be the case in using require_tree)?
If you are using require_tree, there is absolutely no reason to manually require your own files. You shouldn't do so, but it won't hurt if you do since Rails is smart enough to not require the same file twice.
However, you should require files that are "vendorized" or in a gem. "require_tree" won't require those files automatically. It only requires files that are in app/assets/{type}.
There are a handful of of similar questions in SO, but none of them seem to contain a solution to my problem.
Simply put, why am I getting the following error and what can I do to solve it?
$ rake assets:precompile:all RAILS_ENV=production
rake aborted!
File to import not found or unreadable: bootstrap-clubicle.css.erb.
Load path: ~/Clubicle/Source/clubicle
(in ~/Clubicle/Source/clubicle/app/assets/stylesheets/public_portal.css.scss)
There is nothing odd about the #import statement being questioned.
#import 'bootstrap-clubicle.css.erb';
The bootstrap-clubicle.css.erb file does exist, in the stylesheets directory.
I am running Rails 3.1.1 on OSX 10.6.8.
It is also worth noting that I am getting the same error when deploying my app on EngineYard.
The fine support people at EngineYard finally pinpointed the cause of the problem. I had files that were required in application.css (using //= require) that were also included elsewhere (using #import). The double import was causing the issue.
After several painful hours' struggle with this problem, I just want to add another solution that worked for me.
My application.css file looked like this:
/*
* This is a manifest file that'll be compiled into application.css, which will include all the files
* listed below.
*
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
* or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
*
* You're free to add application-wide styles to this file and they'll appear at the top of the
* compiled file, but it's generally better to create a new file per style scope.
*
*/
#import "base";
Notice, I took out:
*= require_self
*= require_tree .
because I was importing another Sass file using the #import directive.
I had to remove the entire comment — not just the requires to get Sass to find my #import "base". Once I did that the import was found and the app precompiled.
Hello I have one question I have my file main.scss which is in public/stylesheets/scss. In documentation is written:
By default, .sass and .scss files are
placed in public/stylesheets/sass
(this can be customized with the
:template_location option). Then,
whenever necessary, they’re compiled
into corresponding CSS files in
public/stylesheets. For instance,
public/stylesheets/sass/main.scss
would be compiled to
public/stylesheets/main.css.
I have in my gemfile gem 'haml'
And from my view I do sth like this
= stylesheet_link_tag 'main'
And the file is not found when I check the source(there is a file with with information about routing error). I guess that compiling it by hand it is not way to go so how I can make compile scss file to public/stylesheets automatic? What mean in documentation that they are compiled when necessary?
Thanks in advance
Put your .sass or .scss files in public/stylesheets/sass, not public/stylesheets/scss. Then the stylesheets should automatically generate whenever you change the corresponding sass/scss file. The generated stylesheets end up in public/stylesheets/.
Renaming the folder should make it all work.
EDIT: it looks like Rails 3.1 is going to be not only including SASS by default, but it will also be moving most of the stuff found in the public folder to the app folder... so this answer will only apply to versions of rails before 3.1.
Rails 3.1 edge use sprockets to handle .js and .scss files.
Sprockets use comments to deal with dependencies.
I put the three folders (dojo dijit dojox) in vendor/assets/javascripts.
Then add a line in app/assets/javascripts/application.js
//= require dojo/dojo
console.log(dojo);
Now dojo has been merged into application.js.
But dojo has dependency system itself. When I require more dojo modules. It cannot find the right path.
dojo.require("dojox.grid.DataGrid");
// Error in webkit console: Error: Could not load 'dojox.grid.DataGrid'; last tried '../dojox/grid/DataGrid.js'
// Error in rails server log: Started GET "/undefined../dojox/grid/DataGrid.js" for 127.0.0.1 at Sat Apr 16 01:26:05 +0800 2011
These are two different dependency systems. How can I put them together?
dojo.js doesn't take too naturally to being renamed. This is because part of Dojo's initialization process involves searching through the DOM for the script tag responsible for loading itself. It does this for two reasons:
Determine its baseUrl if not already specified
Pick up any djConfig (or data-dojo-config in 1.6+) properties specified in the script tag itself
When it searches for this script tag, it looks for one with src set to dojo.js or dojo.xd.js; it's not finding it in your case, thus the failures.
It should be possible to work around both of these issues, by specifying djConfig (or dojoConfig in 1.6+) fully programmatically in another script tag before the one that loads Dojo, and by specifying baseUrl manually in these config properties.
For example, if your application.js were in vendor/assets/javascripts as referred to in your original post, you could try doing this:
<script type="text/javascript">
//if you're using 1.5 or earlier, use djConfig instead of dojoConfig
var dojoConfig = {
//note that baseUrl points to the folder containing dojo.js, therefore the dojo folder
baseUrl: 'vendor/assets/javascripts/dojo/'
};
</script>
<script type="text/javascript" src="vendor/assets/javascripts/application.js"></script>
For more information on dojo config settings: http://dojotoolkit.org/reference-guide/djConfig.html (in fact, that page actually has a note under baseUrl specifically about renamed dojo.js.)
Try adding the dojo files into a dojo/scripts directory under /vendor/assets/javascripts. In the dojo directory, create a dojo.js file in the dojo directory and put //= provide "scripts" in that file.
Then in your application.js file put //= require <dojo>. Check out the Sprockets site http://getsprockets.org/ for info but that should work.
The docs aren't out for Rails 3.1 and the asset pipeline yet so a lot of this stuff is kind of trying to figure out on your own.
Umm... why are you placing your javascripts in vendor and app rather than public/javascripts? you have include anything in public/javascripts with =javascript_include_tag('path_to_javascript') where path_to_javascript would be "dojo/DataGrid" for public/javascripts/dojo/DataGrid.js
http://guides.rubyonrails.org/getting_started.html
I know it's maybe a bit late but I could help someone else.
I finally made it work and posted the explanations here.