I'm getting duplicate asset fingerprint javascript file on Heroku production.
This initially creates around 3-4 files then after a while (a day), it creates another set of those files again. Also every time I refresh those files get rotated in the source.
On production.rb:
config.assets.enabled = true
config.assets.digest = true
config.action_controller.asset_host = "//#{ENV['FOG_DIRECTORY']}.s3.amazonaws.com"
config.assets.initialize_on_precompile = true
config.assets.precompile += %w( '.woff', '.eot', '.svg', '.ttf', '*.css.scss', application_user.js, popcorn.js )
On application.rb:
config.assets.enabled = true
config.assets.digest = true
Surely this doesn't matter?
Structure
The Rails structure is such that it should allow you to use whatever fingerprinted file you need, and it will show (using the dynamic javascript include helpers)
If you're unable to read a particular file because it's not exactly the same as it was before is, in my opinion, a highlight of a poor system design
Files
I think I remember your issue from another day -- you can just use the helper method to call the files you need. It shouldn't cause any issues with the different names. It's all part of the asset pipeline
I'd recommend looking into how you're calling the files - if you're trying to call the hashed filename directly, you're going to have an issue
Related
Rails: 4.2.7.1, Ruby: 2.3.1
We used to use non-hashed assets for serving our assets on our multi-site application by hardcoding the path to the asset in the individual site's headers. We are now pre-compiling hashed assets with Sprockets on each deploy in production with these settings:
production.rb
config.consider_all_requests_local = false
config.action_controller.perform_caching = true
config.serve_static_files = true
config.assets.prefix = "/assets"
config.assets.digest = true
config.assets.initialize_on_precompile = true
We end up with hashed assets, for example, in /public/assets/skins/site1/skin-70ee38249235f8521a243a8f955ed08c.css.
We have a skin file for each path that we use to load our styles per site. We do generate a site application.css that remains unused. Each skin file contains variables for each site and then imports the site's manifest file containing the sass stylesheets.
What we tried to do was create a way for our CMS to look for the hashed asset:
stylesheet_link_tag("/assets/skins/site1/skin.css", media: "all")
The issue is that the site is still looking for the non-hashed skin file. If we have the plain skin.css, it will work.
Same goes for Javascript:
javascript_include_tag "/assets/admin.js"
It will look for the non-hashed asset, even though the hashed asset is present. I tried to remove the "/assets" part from the link tags and it will fail.
Is there a setting that we are missing to have Rails look for the proper hashed asset? Any advice is appreciated.
I am referencing assets in my rails app directly, for ex. background-image: url('/assets/bg.png').
But I just realized this wouldn't work in production since digested assets are served (/assets/bg-dddasd434r4tfdfs...sada.png) in production.
Is my only choice to use helper methods (for ex, image-url) throughout the application or is there a more simpler solution to this?
You can try asset_path('app.js', :digest => false) or disable digest in the prodution env:
# config/environments/prodution.rb
config.assets.digest = false
Rails pipeline
In config/application.rb change the value of
config.assets.digest to false
This is an ancient question, but since I happened upon it with Google...
In Rails 5 there is the asset_path helper which even in the .scss files can return the proper path to a file.
I'm using Rails 3.2.13 and the Rails Asset Pipeline. I want to use the Asset Pipeline so I can use SASS and CoffeeScript and ERB for my assets and have the Pipeline automatically compile them, so I cannot turn off the pipeline in development. I am not precompiling assets in development ever and there is not even a public/assets/ directory.
However, when I make changes to an included file, such as to a _partial.html.erb file that is included (rendered) in a layout.html.erb file, without changing the file doing the including itself (in this example layout.html.erb), Sprockets doesn't detect the change and invalidate the cache, so I keep getting the same stale file. When I'm doing this in active development, I want to disable any caching of assets so I can get the changes on every request but I cannot figure out how to do this. I have set all of the following in my development.rb:
config.action_controller.perform_caching = false
config.action_dispatch.rack_cache = nil
config.middleware.delete Rack::Cache
config.assets.debug = true
config.assets.compress = false
config.cache_classes = false
Still, even with this, files show up under tmp/cache/assets/ and tmp/cache/sass/ and changes are not available on future requests. Right now I have to manually delete those directories every time I want to see a change.
Unfortunately, the entire contents of the How Caching Works section of the RoR Guide for the Asset Pipeline is:
Sprockets uses the default Rails cache store to cache assets in
development and production.
TODO: Add more about changing the default store.
So, how can I get Sprockets to compile assets on demand but not cache the results?
Here's the magic incantation:
config.assets.cache_store = :null_store # Disables the Asset cache
config.sass.cache = false # Disable the SASS compiler cache
The asset pipeline has it's own instance of a cache and setting config.assets.cache = false does nothing, so you have to set its cache to be the null_store to disable it.
Even then, the SASS compiler has it's own cache, and if you need to disable it, you have to disable it separately.
I created the following gist (https://gist.github.com/metaskills/9028312) that does just this and found it is the only way that works for me.
# In config/initializers/sprockets.rb
require 'sprockets'
require 'sprockets/server'
Sprockets::Server.class_eval do
private
def headers_with_rails_env_check(*args)
headers_without_rails_env_check(*args).tap do |headers|
if Rails.env.development?
headers["Cache-Control"] = "no-cache"
headers.delete "Last-Modified"
headers.delete "ETag"
end
end
end
alias_method_chain :headers, :rails_env_check
end
The accepted answer is not doing it correctly and it degrades the performance in development by disabling cache totally.
Answering your original question, you want changes to referenced files to invalidate the asset cache even if not included directly.
The solution is by simply declaring such dependency such that sprockets knows that the cache should be invalidated:
# layout.html.erb
<% depend_on Rails.root.join('app').join('views').join('_partial.html.erb') %>
# replace the above with the correct path, could also be relative but didn't try
Below is the asset host config of my Rails app
ASSET_HOSTS = ["http://host1.cdn.com", "http://host2.cdn.com"]
config.asset_host = proc do |path, request=nil, *_|
ASSET_HOSTS.sample
end
The problem with this is that one of my javascript files (which is a .js.erb file) has a different digest (when called by javascript_include_tag) than the one specified in manifest.yml (generated during precompilation).
Does anyone know why this happened and how to fix it?
I recently migrated from Jammit to the Rails Asset Pipeline. Other than a few teething issues, everything has been working well.
However, I recently started getting some script errors in production, and realised that it's near on impossible for me to debug them. I had previously configured Jammit to retain linebreaks, but otherwise remove all white space in the javascript files. This was to ensure that should I see a runtime error, I would be able to locate the offending line and hopefully figure out what the problem is. With the Rails Asset Pipeline, and the default :uglifier compressor, it appears all whitespace is removed including line breaks, and as such my script errors do not tell me where in the code the problem was.
Does anyone know anyway to configure the Rails Asset Pipeline to retain line breaks so that code can be debugged?
Matt
Set in you production.rb:
config.assets.compress = false
and running rake assets:precompile won't uglify your assets.
UPD:
So-called compression means (among other stuff): remove line breaks and comments.
But if you want to obfuscate your variables and save some readability then use:
# in production.rb
config.assets.compress = true
config.assets.js_compressor = Uglifier.new(:beautify => true) if defined? Uglifier
Here see for more options: https://github.com/lautis/uglifier.