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.
Related
I'm trying to debug why some assets are found and others not in the Asset Pipeline. i've tried a lot of obvious things (like typos, clearing tmp, clean/clobber).
Now I placed binding.pry right before where the image path is generated, and I'd like to view (print to the rails console / debugger) the name of every asset rails thinks is available.
How can I do that?
You can take a look at the manifest:
Rails.application.assets_manifest
# or just the files
# this is empty in some of my apps, no idea why, maybe cache or some
# lazy loading that I'm missing:
Rails.application.assets_manifest.assets
Or maybe loop through asset paths:
Rails.configuration.assets.paths.flat_map{ |path| Dir.glob("#{path}/*.{js,css}") }
Please note, this doesn't answer the question (how to view the available assets in the console/debugger), and therefore shall not be accepted as an answer, but it's a small start: showing how to view assets from the terminal:
rails webpacker:clean
rails webpacker:clobber
rails webpacker:compile
The last step will print all the available assets to the terminal.
Another way is to run bin/webpack from the terminal, and in the output will be each asset. Again, this doesn't provide the list from the console or debugger.
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
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
The Rails Guide on the asset pipeline says you can use the yui-compressor on CSS with:
config.assets.css_compressor = :yui
However, I see no sign that it is actually using it. For one, thing, it makes no difference whether or not I have the yui-compressor gem installed or not. For another, compressed output is the same whether I have that line or not.
I put a little debug line into actionpack-3.2.3/lib/sprockets/compressors.rb in the registered_css_compressor method, and this is the result when the css is compiled: #<Sass::Rails::CssCompressor:0x007fdef9f9fee0>
So it appears that the config line is not being honored. Has anyone actually used this option?
Update
Looking in sass-rails shows that the selection is overridden:
if app.config.assets.compress
app.config.sass.style = :compressed
app.config.assets.css_compressor = CssCompressor.new
end
If I comment that out, then it actually attempts to start the yui compressor... I'm still checking the output to see if it is correct.
It truly is a bug in rails. I created a patch and pull request to fix it.
I have added these two lines to application.rb:
config.assets.initialize_on_precompile = false
config.assets.compile = true
However I still get errors when I push to Heroku:
2012-02-05T09:48:34+00:00 app[web.1]: Completed 500 Internal Server Error in 3ms
2012-02-05T09:48:34+00:00 app[web.1]:
2012-02-05T09:48:34+00:00 app[web.1]: ActionView::Template::Error (bootstrap.css isn't precompiled):
Any suggestions?
By the looks of it you have a bootstrap.css file that is not included properly in your manifest file within app/assets/stylesheets and that you're probably also calling directly from a stylesheet_tag.
There are a couple of approaches to this:
You could add a line to your environment config file which will ensure the css file you're calling is precompiled:
config.assets.precompile += %w( bootstrap.css )
…for example.
This is the one i would probably do; include the bootstrap.css file in a manifest file inside `app/assets/stylesheets' as mentioned above. Your manifest file will look something like this (not sure if the formatting of this will appear correctly on here, so i have also created a Gist: https://gist.github.com/1753229):
/*
*= require bootstrap
*/
/* rest of file omitted */
You might need to require more files than that depending on what your css setup is.
Try to use rake assets:precompile before committing your code and pushing it to heroku.
read this, it's a tutorial on how to get rails 3.2.1 (and ruby 1.9.3) running on heroku. You can obviously skip the bits you don't need but it should explain why these problems are happening and how to fix them.
Also, read this article by david rice, author of the useful asset_sync gem. It will help you sort this out.