javascript_include_tag inconsistent behavior - ruby-on-rails

Working with Ruby 2.0 and Rails 4.0, I'm seeing a different behavior on my asset pipeline and I'm not sure why. Here's the gist of it...
I have in my ./app/assets/javascripts folder an application.js.coffee and google_analytics.js.coffee file.
In my app/views/layouts/application.html.haml, I have the following two lines:
= javascript_include_tag "application"
= javascript_include_tag "google_analytics"
This produces the following in the rendered page once deployed to production:
<script src="/assets/application-f15feb4200e0d1db4963a00b28fbe9ca.js"></script>
<script src="/javascripts/google_analytics.js"></script>
Note that the application include is compiled into the assets pipeline as expected, while the google_analytics script is not.
In development mode, everything's served from the assets pipe without the fingerprints as expected:
<script src="/assets/jquery.js?body=1"></script>
<!-- several other includes suppressed for brevity here -->
<script src="/assets/application.js?body=1"></script>
<script src="/assets/google_analytics.js?body=1"></script>
I also checked the production deployment and noted that google_analytics doesn't get pre-compiled and fingerprinted.
EDIT: After getting the comments and answers below, added the following to config/environments/production.rb and attempted another deploy:
ComingSoon::Application.configure do
config.serve_static_assets = false
config.assets.js_compressor = :uglifier
config.assets.compile = false
config.assets.digest = true
config.assets.version = '1.0'
config.assets.precompile += ['google_analytics.js.coffee']
end
Why is the sprockets assets pipeline not pre-compiling the google_analytics script and serving it up like it does the application script? how do I fix this?

You can add the google script to the precompile list in your config/environments/production.rb file on the config.assets.precompile setting. More here: What is the purpose of config.assets.precompile?

The google_analytics file needs to be added to the precompile list:
config.assets.precompile += ['google_analytics.js.coffee', ..]
Add above to your application.rb or production.rb as desired.
Note: Unless you have required the file in the application.js manifest file, through a direct require or through a require_tree, the js doesn't get compiled.

Related

Assets not compiling

This is driving me crazy - changes to css on my rails site only update when I run rake assets:precompile.
Does anyone know how to fix this, so assets will get compiled as they are changed?
I have a hunch the issue is in this config/environments/development.rb file:
Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb.
config.assets.compile = true
# In the development environment your application's code is reloaded on
# every request. This slows down response time but is perfect for development
# since you don't have to restart the web server when you make code changes.
config.cache_classes = false
# Do not eager load code on boot.
config.eager_load = false
# Show full error reports and disable caching.
config.consider_all_requests_local = true
config.action_controller.perform_caching = false
# Care if the mailer can't send.
config.action_mailer.raise_delivery_errors = true
# Print deprecation notices to the Rails logger.
config.active_support.deprecation = :log
config.action_mailer.delivery_method = :smtp
config.action_mailer.perform_deliveries = true
config.action_mailer.default_url_options = { :host => "http://localhost:3000/" }
# SMTP settings for gmail
config.action_mailer.smtp_settings = {
address: 'smtp.gmail.com',
port: 587,
domain: 'gmail.com',
user_name: ENV['gmail_username'],
password: ENV['gmail_password'],
authentication: 'plain',
enable_starttls_auto: true
}
# Raise an error on page load if there are pending migrations.
config.active_record.migration_error = :page_load
# Debug mode disables concatenation and preprocessing of assets.
# This option may cause significant delays in view rendering with a large
# number of complex assets.
config.assets.debug = true
# Asset digests allow you to set far-future HTTP expiration dates on all assets,
# yet still be able to expire them through the digest params.
config.assets.digest = true
# Adds additional error checking when serving assets at runtime.
# Checks for improperly declared sprockets dependencies.
# Raises helpful error messages.
config.assets.raise_runtime_errors = true
# Raises error for missing translations
# config.action_view.raise_on_missing_translations = true
end
Here is the top of my assets/stylesheets/application.css file:
/*
* 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 any plugin's vendor/assets/stylesheets directory 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 bottom of the
* compiled file so the styles you add here take precedence over styles defined in any styles
* defined in the other CSS/SCSS files in this directory. It is generally better to create a new
* file per style scope.
*
*= require_tree .
*= require_self
*/
As well as the top of application.js:
// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// compiled file.
//
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require jquery
//= require jquery_ujs
//= require_tree .
Edit: I should add that this only became a problem once I removed bootstrap...
To solve the issue:
rake assets:clobber
OR
delete the public/assets folder
From the comments above: Assets not compiling

Why won't the Rails asset pipeline compile a CSS manifest when it's not called "application.css.scss"?

Up until now all of my application's CSS has been served through application.css.scss which looks like this:
/* ...
*= require jquery-ui
*= require_self
*= require_tree .
*/
#import "bootstrap";
I recently needed to create a separate, stripped down manifest file that was to serve only a single embeddable asset in our website. Unfortunately though I couldn't get the CSS file to be packaged up and processed by the asset pipeline. It kept getting put into production with a URL that looked like this:
<link href="/stylesheets/minimag.css" rel="stylesheet" />
rather than what it should have looked like with fingerprinting and precompliation which would be more like:
<link href="/assets/minimag-292d6edcd4fd2398abab273acf8.css" rel="stylesheet" />
On debugging I discovered that the manifest HAS to be called application.css
There's a good chance I'm missing something. BUT on stripping the problem back to its bare essentials I looked just at the application's stylesheet itself.
What I found was that when it was called application.css.scss, it was compiled just fine but when the name was changed it didn't get processed:
So this works:
application.html.haml
...
= stylesheet_link_tag "application"
...
together with a stylesheet called application.css.scss. In production this yields the inclusion HTML:
...
<link href="/assets/application-292d6edcd4fd6ec1da12b93fb273acf8.css" rel="stylesheet" />
...
But this does not work
application.html.haml
...
= stylesheet_link_tag "testing"
...
together with exactly the same stylesheet but now renamed to testing.css.scss. In production this yields the inclusion HTML:
...
<link href="/stylesheets/testing.css" rel="stylesheet" />
...
What makes "application.css.scss" special?
Why is this going on? Why can't I just use a manifest file that has any old name?
(if it's at all relevant I'm deploying to Heroku)
You have to add stylesheets to the precompilation if you want to use them as a standalone file.
# config/environments/production.rb
# Precompile additional assets.
# application.js, application.css, and all non-JS/CSS in app/assets folder are already added.
config.assets.precompile += %w(testing.css)

No route matches [GET] "/stylesheets/frontend.css"

Ruby Version: 2.0.0
Rails Version: 4.0.1
This is a follow-up to my previous question: Why do assets fail to load in production mode?. This was mostly fixed by setting config.serve_static_assets = true in production.rb.
However, now I still have one stylesheet and one javascript file that aren't being pulled in. which (coincidentally) should be pulling in it's own set of dependencies.
In my application.html.erb file I have:
<%= stylesheet_link_tag "application", media: "all" %>
<%= stylesheet_link_tag "frontend", media: "all" %>
However, that seems to be parsing to two very different things. Here is the output:
<link href="/assets/application-1c1eb49916824f465443a709172a580a.css" media="all" rel="stylesheet">
<link href="/stylesheets/frontend.css" media="all" rel="stylesheet">
And in case it makes a difference, here is what frontend.css actually looks like:
/*
* 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.
*
*= require_self
*= require_tree ./frontend
*= require front_end
*/
What am I missing?
In config/application.rb, add frontend.css to config.assets.precompile:
# Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added)
config.assets.precompile += %w( frontend.css )
Don't forget to do this if you create other CSS and JavaScript manifest files.

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" %>

javascript_include_tag Rails 4 generating "/javascripts/" instead of "/assets" in production

I have a Rails 4 application with
<%= javascript_include_tag "modernizr", "data-turbolinks-track" => true %>
in the head. In development, the following HTML is rendered, and modernizr is loaded:
<script data-turbolinks-track="true" src="/assets/modernizr.js?body=1"></script>
In production, the followign HTML is rendered, and modernizr is not loaded (404 not found):
<script data-turbolinks-track="true" src="/javascripts/modernizr.js"></script>
In production, /assets/modernizr.js is found and browsable.
The Rails documentation says that the javascript_include_tag should generate
<script data-turbolinks-track="true" src="/assets/modernizr.js?body=1"></script>
In production, my stylesheet_link_tags are fine, linking to the /assets/ directory.
Why is the javascript_include_tag linking to /javascripts instead of /assets in production, and how can I fix it?
One of the usage statements for AssetUrlHelper indicates it will produce /javascripts/ urls
like what you are seeing:
# asset_path "application", type: :javascript # => /javascripts/application.js
(from asset_url_helper.rb line 117 - [1])
This code looks like it can only be reached if the precompiled asset is missing
so it would appear that your asset compilation is not working (my deployments usually
fail when that happens, so maybe yours isn't even firing).
The same asset_url_helper.rb calls the /javascripts/ part 'extname' and
uses the following map to know how to generate the name:
# Maps asset types to public directory.
ASSET_PUBLIC_DIRECTORIES = {
audio: '/audios',
font: '/fonts',
image: '/images',
javascript: '/javascripts',
stylesheet: '/stylesheets',
video: '/videos'
}
A new Rails 4 app has this in the config/environments/production.rb
# Do not fallback to assets pipeline if a precompiled asset is missed.
config.assets.compile = false
which seems to match the behavior you are seeing.
By default, Rails only precompiles application.js, application.css and any images it finds in the assets path. Therefore, in production mordernizr will not get precompiled and thus the javascript helpers will not be able to find the file.
In order to fix the issue, you can add modernizr to the precompile list by modifying the following config in production.rb
config.assets.precompile += ['modernizr.js']
For more information see the Rails Guides
Be sure to precompile your assets in production by running this command:
RAILS_ENV=production bundle exec rake assets:precompile
The Rails Guide on the asset pipeline can give you more details: http://guides.rubyonrails.org/asset_pipeline.html#precompiling-assets
I have a new application using Rails 4 deployed on Heroku with :
<%= javascript_include_tag "application", "data-turbolinks-track" => true %>
my javascript application.(fingerprint).js called from the src: assets/application.js
i think your problem come from something into your production.rb who define assets from another location.
So maybe you can add Moderniz.js to
config.assets.precompile = ['.js', '.css', '*.css.erb']
in config/production.rb
Or simply require modernizr script into your application.js
//= require mordernizr
and remove the modernizr script call into your layout.
<%= javascript_include_tag "modernizr", "data-turbolinks-track" => true %>
Can you check from where your application.js is served into your production environment ?
It may be because this file needs to be in /vendor/assets/javascript instead of /app/assets/javascript. The Vendor folder is for javascript libraries, and the App folder is for your code.
A better solution than adding a tag to your layout would be adding a script reference to your application.js and let the sass compiler compress and attach it to your main javascript file.
If you don't get a definitive answer, check out:
http://guides.rubyonrails.org/asset_pipeline.html#asset-organization

Resources