How to "auto-build" and load different CSS stylesheet files when running a 'development' and 'production' mode? - ruby-on-rails

I am using Ruby on Rails 3.0.10 and I would like to auto-build and load different CSS stylesheet files depending on if I am running my application in the development or in the production mode.
I would like to auto-"minimize" CSS files for performance reasons and to load those related "minimized" files because I do not want to show to the "public audience" the content of my comments present in my CSS file (note: users can access theme, for example, by using the FireBug plugin for the Mozilla Firefox browser). I would like to do that also for javascript files.
How can I do that?
P.S.: I am planning to switch to the Ruby on Rails v3.1...

In your layout you probably have something like:
<%= stylesheet_link_tag "production.css" %>
Just add another stylesheet there but wrap it in a conditional that checks the rails environment.
<%= stylesheet_link_tag "development.css" if Rails.env.production? %>

For Rails 3.0 there are many plugins to minify your css and javascript.
I use smurf.
gem "smurf"
Part of the process of minification is that it removes comments.
In Rails 3.1 production will uglify your javascript, so comments should be removed by default.
But if you insist on using a different stylesheet, take a look at the other answer.

Related

Print styles not applied in production with webpack / react

I am running a stack with rails, react on rails, and webpack.
I am able to use print styles successfully in development, however when deploying to production it seems that none of the print styles apply.
In Development
In Production.
Only appears on production.
Possibly move towards PDF similar to other pages.
Style exists in production, not being applied properly?
In production it is able to find the media print styles.
Style in production
#media print{.App-module__d-print-active-pdf___2FlpM{background-color:#fff;height:100%;width:100%;position:fixed;top:0;left:0;margin:0;padding:15px;font-size:14px;line-height:18px}}
In Production.
UPDATE:
Print styles are applied properly from the assets folder.
However they are not applied from the applications bundle.
If using webpacker, be sure to set the media type on your style tags:
So instead of:
<%= stylesheet_packs_with_chunks_tag 'styles-bundle' %>
You would want
<%= stylesheet_packs_with_chunks_tag 'styles-bundle', media: 'all' %>
If you'd like more info, the source for this can be helpful:
webpacker docs on stylesheet_packs_with_chunks_tag
Rails asset tag helper docs

Why can't I add a plain link tag in Rails4 App

Why is it so forbidden to add line like <link href="/assets/stylesheets/bootstrap/bootstrap.css" rel="stylesheet"> in my application.html.erb file. How else do I insert it?
It's not "forbidden" outright - it just skirts a lot of important Rails conventions which will likely create problems & inconsistencies down the line
There are several elements to what you're asking. Here they are:
Layout
Firstly, you need to use the correct helpers in your layout:
#app/views/layout/application.html.erb
<%= stylesheet_link_tag "bootstrap/bootsrap" %>
The reason for this is the same as using helpers in other parts of your Rails application - as paths change between environments & certain "backend" functionalities of the system evolve, you can't rely on using vanilla HTML to call "Rails-centric" methods
A pro tip is that if there is any reference to a path, or an asset, you need to use the helpers which Rails provides
Asset Pipeline
Further to this, you need to appreciate how the "asset pipeline" works.
One of the big benefits of the Rails framework is that it gives you the ability to organize your assets in the most effective way - by keeping them in the /assets folder.
Whilst great for development, your problem will arise when you go into a production environment - Rails prefers to serve static assets in production, which means that the assets will be pre-compiled & access in the public folder:
In the production environment Sprockets uses the fingerprinting scheme
outlined above. By default Rails assumes assets have been precompiled
and will be served as static assets by your web server.
To make sure this works properly, you need to use the path helpers to load the files dynamically; hence allowing Rails to access the files wherever they are on the system
--
Manifest
I would strongly recommend you look into the "manifest" feature of the asset pipeline:
#app/assets/stylesheets/application.css
/*
*= require bootstrap/bootstrap
*/

Angular + .nghaml template: Referencing Precompiled Image Assets

I'm using .nghaml for my templates and using the following gems for Angular integration:
gem 'angularjs-rails'
gem 'angular-rails-templates'
My Rail view layouts are name.html.haml and using image_tag within them works fine. On production I can see the images.
In contrast, in my Angular templates (assets/template) with their .nghaml extension I can not use Rails helper image_tag and a direct reference does not work
%image(src="assets/sample_image.png")
The direct reference works locally, but on production images don't render.
This person (Rails Image assets in Angular Directive and template) had a similar issue, but using
%img(ng-src='assets/sample_image.png')
worked locally but not in production. And attempting to use image-url results in the error of undefined method (just as image_tag) because none of the Rails helpers seem to be working in the .nghaml extension.
The images that are working (Rails views with image_tag helpers) are referencing the precompiled assets which have their names changed with the addition of a md5-hash (based on the first linked article), but I'm having issues figuring out how to tell the nghaml templates what the new precompiled assets are called without a Rails helper method.
I ran into this issue with helpers a few months ago (Rails App to Angular: HAML + Rails Helpers) and didn't find a solution, but only recently needed to get images into nghaml templates rather than just creating what I needed with CSS.
I'm currently planning to just move the angular templates back to erb if I can't get this figured out, but if there are alternatives (or solutions) I'm unaware of, I'd love to hear them.
The solution proposed in the post Rails App to Angular: HAML + Rails Helpers will allow you to use the helpers (including the image_tag helper) in your haml files when generating the client-side html files.
One issue: According to the official repo for the angular-rails-template library, the .nghaml extension is no longer supported. You have to rename it to .haml
The bigger issue is that you're using Rails to serve a single-page JS app. There's no need for this, you can serve the site using nginx or Apache and control the caching and do cache busting there (nginx & apache cache busting tutorial)
If you're using Rails for the REST API, it should be de-coupled from your frontend AngularJS app.
If you're trying to do some fancy stuff in the templates aside from the cache busting, you should be doing it in JS and plain HTML. It's weird and strange but AngularJS and other frontend MVC/MVVM frameworks are different beasts compared to Rails and Django and the server-side MVC frameworks.

Rails 3.1 Assets are being fingerprinted in production but rendered HTML is not

Everything works great in Development. And app deploys as normal with Capistrano. Assets (javascript & css) appear to be fully pre-compiled and each, along with images, are given a "fingerprint". Problem is when using image_tag("image-name.png") in my view the html it creates in production doesn't include the 'fingerprint'.
The rendered HTML we get in production:
<img alt="Image-name" src="/assets/image-name.png" />
instead of, what I would expect, should be:
<img alt="Image-name" src="/assets/image-name-b89cae2830c2901f844c353b3f3942fe.png" />
So which of Rails 3.1's myriad config options did we botch?
Edit
The troublesome images appear to be those included in a 3rd-party Colorbox image viewing tool we use. Rails 3.1 is fingerprinting its assets (border.png, etc.) but, clearly, the source code for this javascript library doesn't use helpers like image_tag. So in production it is still looking for images named /assets/colorbox/border.png. Currently images are in /vendor/assets/images and work fine in Development. Is there a way to prevent just these images from being "fingerprinted"?
Well, here's how I hacked the 3rd-party files to make things work:
The offending images were in files like vendor/assets/stylesheets/colorbox.css. I first changed the extension of the files to .scss then I changed each url(colorbox/image.png) to image_url("color box/image.png") and now everything is peachy. Assets are served normally in development and fingerprinted in production.
Still like to see the "proper" way to add 3rd-party (vendor) javascript libraries & css to a Rails 3.1 app. Rails team must have anticipate a drop-in solution that doesn't require editing?!? So, please, feel free to offer up other solutions.
Aside: where I previously had manually configured my Capistrano recipe with:
run "cd #{release_path}; RAILS_ENV=production bundle exec rake assets:precompile"
…and its accompanying after deploy:update_code …. I have now removed those lines and instead added load 'deploy/assets to my Capfile. I don't think this makes any difference in the above problem but I wanted to document it anyway as adding your own recipe for pipeline precompiling is no longer necessary in Capistrano 2.8 as it was in the 3.1rc days.

In Ruby on Rails how can I combine multiple Javascript files at runtime?

I am building a Facebook App which is heavy on Javascript. For this I have multiple Javascript files. Since in Facebook development, the page is served over a tunnel, there is excessive latency added while requesting multiple javascript files. Is it possible to combine the contents of multiple javascript files at runtime? Having multiple files makes it easy to develop, and hence I am avoiding having to combine it while development itself.
You can pass a :cache option to the javascript_include_tag which will combine the files into one:
<%= javascript_include_tag :all, :cache => true %>
Note that this depends on ActionController::Base.perform_caching being set to true, which it is by default for the Rails production environment.
See http://api.rubyonrails.org/classes/ActionView/Helpers/AssetTagHelper.html#M001493
in your config file for the environment located at /config/environments, you have a file for each, like development.rb and so on.
In that file, you can set config.assets.debug = false
and that will reduce files down to 1 js file, and 1 css file.
Better than combining at runtime, have a look at Frizione. It's a framework that will allow you to combine your javascript files at deploy time, and compress them. So you get to save all around. It throws in doc generation and JSLint checking as well, but that's just an added bonus.
Jammit is a good catch too, to combile js and css files.
http://documentcloud.github.com/jammit/
I've used the asset_packager gem to do this in my applications.
It will combine and minimize your javascript (and CSS) files for production and adds some view helpers that make it very easy to use. There's a rake command that you run to generate the packaged files if the originals have changed.

Resources