Coffeescript import and organization for Rails - ruby-on-rails

I'm building a Rails application that is almost entirely CoffeeScript upfront. The user will never wait for a page redirect because literally everything happens on the front page (a la Twitter).
Now I've had to put all of my CoffeeScript into one file because my jQuery onLoad is complex and, while in production it will be compiled to one JS file, in testing this is not the case.
How can I either import CoffeeScript from other files in development or organize my CoffeeScript so I'm not piling 500 lines into one file (when those 500 lines contain 5/6 distinct domains)?
I have used import in SCSS to do the same thing for my stylesheets, but CS is proving a bit trickier.

The asset pipeline allows you to require different files into one file, which keeps them separate in development and compiles them to one file in production. Check out the instructions on Manifest files and Directives
Also, have you looked into RequireJS? It can work in or outside of Rails and might be the sort of thing you need.

Related

rails 4.2 assets loading

I'm playing with a rails 4.2 application and it seems like it loads all of my stylesheets for each and every page.
Is that true? How is it better than loading for each page only the relevant stylesheets?
On one hand, I know they'll all be minified when going to production, and it will reduce the total size and cache one CSS for the whole website.
On the other hand, page I might have some thin pages that will need no more than a few css lines to be rendered correctly that will get tones of files for no reason. It will also require me to be super strict and safe when choosing class names in order to have no collisions and unwanted overrides.
What about JS assets? It acts the same way?
(I guess the answer for image assets is "hell no!")
Yes, in development you'll see a lot of files (all of them) and in production they will be compiled and minified to a single file.
Once this file has been downloaded by the client it will be cached and wont need to make any further requests to load other stylesheet files on concurrent request (unless caching and turbolinks has been disabled). The downside is that the file size will be larger and make the initial load time slightly longer.
One problem as you point out is scoping. In my experience it's way better to always apply proper scopes when developing. And in rails using sass it's really easy to have nice and tidy css.
The same goes for javascript, but not for images as you pointed out.
That said. There are ways to work around this if desired, but more often than not I've realized that there are more pros than cons with a single file.
Edit:
Oh, and if you're new to rails, beware that turbolinks might cause you some headaches in the beginning messing with page ready in js-files before you get the hang of it. But it's worth it in the end.
The advantage and rationale for this is to reduce the amount of data that is sent to the client after the first page load. The first page load pulls down all the js/css (compiled into single files), but then this can be cached and reduces the amount on each subsequent page load.
The following is purely theoretical, if at all possible, try and work with the defaults of one css/jss file
If you absolutely do want to trim it down, then you can. Your application.css manifest file (or js) probably includes a line such as:
//= require_tree .
which says, require everything in this directory. you could then split this down so application.css only requires everything in the application folder (absolutely need to know):
//=require_tree ./application
Then add additional manifest files, for example for an admin section, so that the admin styles/JS can be loaded only when needed in admin.js
//=require_tree ./admin
Then in your layout file you can do
= stylesheet_link_tag "application", media: "all"
= yield :additional_stylesheets
And where you want those additional styles you can add them.
- content_for :additional_stylesheets do
= stylesheet_link_tag "admin", media: "all"
end
Note: this will cause issues if you're using turbolinks.
Note II: You may need to add these to the precompile list in application.rb:
config.assets.precompile += ['additional_manifests.css']
You could modify this workflow to not include any CSS at all to start with and only load what you need.

Precompile Grails CoffeeScript assets for Testing with Geb

I would like to create reliable functional tests for Grails application with Geb which wouldn't take ages to run so me and and other team members can run them before each commit. I'm using Grails Asset Pipeline with CoffeeScript files split into many files and grouped using index files.
The problem is following:
In development and test environment the CoffeeScript files are compiled for the first URL hit - for the first time the page is loaded. As the application grows this takes more than one minute (especially on CI server) so each of my Geb specification needs to start with waitFor(120){...} to ensure the specification will wait until the CoffeeScript get compiled.
I could run the functional tests with -war flag but than all the CoffeeScript files present get compiled multiple times (once for every reference from the CoffeeScript file, i.e. one big bundle or the application coffee, once for index file once for the file itself). Currently the compile process fires for nearly three hundreds of files instead of two. If I try to exclude some files using the grails.assets.excludes than the files are missing from the application bundle completely.
Are there any suggestion how can compile just the files which are needed but not excluding them from bundling into other files?
The structure can be seen in our test app and core plugin.

Using ExtJS along with the Rails Assets Pipeline

For an application built on top of Rails (3.1.8) with ExtJS 4.1, we have the following files layout:
app/
assets/
javascript/
application.coffee
WID/
Lots of coffeescript files and folders.
public/
extjs/
ext-all-debug-w-comments.js and the whole ExtJS framework.
Our application heavily relies on the Ext loader (Ext.Require) to dynamically load files based on users rights / allowed modules. We would like to keep this functionality as much as possible, so only the required files are requested from the server. Bandwidth isn't really an issue, as the application is intranet-based (On a LAN).
In development environment, everything runs smooth. In production environment however, we are having problems. It looks like either the "rake assets:precompile" task is concatenating all files into an application.js file, and then when accessing our application the Ext loader complains that it can't find individual files (Because assets/WID/.../file.js isn't being served by the rails server).
So right now, i'm not sure what would be the best move to take... Is there anyone able to help us with a successful Rails + ExtJS production setup taking the best from the assets pipeline?
Thank you,
Pierre.
I think you should move your javascripts (and generally all the assets) from your public into vendor/assets/javascripts when you are in development environment. This way the asset-pipeline gets in charge.
EDIT: You may consider reverting your manifest file to application.js, not application.coffee. Generally it is a bad idea to rename these special files : application.css and application.js .In case you have some coffescript to add , just create a new file and place it in an asset directory.

Rails 3.1 asset pipeline - missing files from public/assets - why isn't this the default?

After I deployed my upgraded Rails 2.3.x -> 3.1 (rc4) app to our test environment this afternoon, all of our stylesheets and JavaScript files were returning 404 errors. We had added the rake assets:precompile task to our post-deploy script and it took a while to determine why the assets folder didn't have the pre-compiled files we expected.
In the end, the files weren't being compiled because apparently only application.css and application.js (+ non JS/CSS files) are processed by default.
We needed to change the following configuration value as follows:
config.assets.precompile += %w( *.js *.css )
Question: why isn't this the default?
I would have expected that anything that wasn't necessary to process as a manifest file would just get copied into public/assets. Much of what I've read on the asset pipeline is essentially "stick your assets in app/assets, configure the manifest files, and it should just work". Since the assets:precompile task didn't spit out any information about what it was doing, it took a while to determine that it just wasn't looking at the files we thought it would.
Is there any reason why this would not be a good value for the precompile configuration?
Thanks!
The idea is to have all your JavaScript and CSS always loaded in one shot, rather than loading bits and pieces as you move along. That way you always have the 'world' loaded and ready to work with, rather than having to include a whole bunch of individual files here and there.
It's a bit of a larger 'up front' load, but then the browser should keep loading all the javascript from cache. So the perceived speed of the site should speed up due to having everything cached and ready to go after the first request.
This was a controversial decision to include for Rails, but so is including CoffeeScript by default. Rails has always been an opinionated framework that way.
the new sprockets-based pipeline compiles all the files in /asssets/stylesheets and /assets/javascripts get compiled into application.css and application.js, respectively, by default.
In your views, you only need to link the application files, sprockets handles the rest.
Update:
Well, you don't have to make it all into just one file... You could have an shared.js, secure.js and public.js and have them each include the parts they need...
Think of them not as javascript files, but manifest files that establish groups of javascript files which you can then include as a group with a single javascript_include_tag. While the default is to include everything in the folder into a single file, you can be always pick and choose what to include, and what not.
The 'precompile' task simply runs those manifest files and compiles the multiple files into one, while pre-processing and sass or coffee script it runs across.

Ways to organise CSS in Rails project

I would like to know what are the best ways to organise CSS code in Rails project?
I'm interested in how you do it and why.
If you would like to break up your css into multiple files during development you can add cache => true to stylesheet_link_tag and rails will automatically concatenate them into a single file in production. This also works for javascript_include_tag.
http://guides.rubyonrails.org/layouts_and_rendering.html#linking-to-javascript-files-with-javascript_include_tag
Generally, you should not have the client download a massive amount of CSS snippets, but pack them into a single file on the server to avoid rendering latencies. So you have the tradeoff of having functionality divided up into multiple files put wanting to send only one file to the client.
You could use SASS to have each piece of code inside a single include file and just include all of them together. This gives you the added advantage of mixins (kind of like macros) and variables among other awesome things.
Another possibility would be to use plain CSS and use something like Jammit to pack the stuff up to send to the client.
Regarding actual setups, I tend to have one file resetting the styles to a known default, a file for the basic layout (columns, default spaces, ...), and one file each for each area of concern for your specific design (headers, buttons, ...)
James and Holger's answers are very good.
Besides organizing CSS in my projects, I also had to change colour schemes a couple of times..
Trying to do consistent changes throughout many CSS files can be pretty painful (results may vary).
I ended up extending the Rails start-up procedure a little, to include a custom module "site_settings.rb"
through which I can define variable for colors and other CSS attributes, which I can then use throughout my CSS input files.
Whenever Rails starts up, and one of the input files has changed, it auto-generates the CSS files.
http://unixgods.org/~tilo/Ruby/Using_Variables_in_CSS_Files_with_Ruby_on_Rails.html
Since Rails 3.1 is out and sprockets replaced Jammit, here an excerpt form the Rails guides concerning the asset organization:
Asset Organization
Assets can be placed inside an application in one of three locations: app/assets, lib/assets or vendor/assets.
app/assets is for assets that are owned by the application, such as custom images, JavaScript files or stylesheets.
lib/assets is for your own libraries’ code that doesn’t really fit into the scope of the application or those libraries which are shared across applications.
vendor/assets is for assets that are owned by outside entities, such as code for JavaScript plugins.

Resources