Rails 3.2 and yui compressor - ruby-on-rails

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.

Related

How can I peek at intermediary files processed by asset pipeline?

I've got somefile.js.coffee.erb file which is processed by Rails asset pipeline. My ERB code returns some string that cannot be parsed by Coffee which result in SyntaxError exception. I would like to peek into generated somefile.js.coffee file, or in general any intermediary file processed by asset pipeline.
I've tried to examine Sprockets with no luck:
environment = Sprockets::Environment.new
MyApplication::Application.config.assets.paths.each {|p| environment.append_path p}
rerb = environment['somefile.js.coffee.erb']
rerb.source #=> it's already preprocessed
Or to look into \tmp\cache\assets but there are also only preprocessed files, additionaly obscured by fingerprinted name.
Maybe there is a way to hook into asset-pipeline I have no idea how..
Why I need ERB? To generate client-side-model stubs with fields and validations matching Rails model using KnockoutJS (https://github.com/dnagir/knockout-rails extended -> https://github.com/KrzysztofMadejski/knockout-rails).
I am using Rails '~> 3.2.12', sprockets (2.2.2).
Edit: I've ended up injecting erb code in ### comments, to sneak-peak at generated code while coffeescript file is still compiling:
###
<%= somefun() %>
###
Altough I would suggest using #Semyon Perepelitsa answer as it produces coffee script file as it is seen by coffee compiler.
Just remove "coffee" from the file extension temporarily: somefile.js.erb. You will see its intermediate state at /assets/somefile.js as it won't be processed by CoffeeScript.
I wonder if you can put <% binding.pry %> just before the line and mess around till you get it right. Never tried during a compile and don't use coffeescript. In theory, it should work (or is worth a shot) so long as you put gem pry in your Gemfile and run bundle first.

Rails asset pipeline and javascript files - maintaining line breaks to aid debugging

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.

Why does Rails not refresh classes on every request (despite configuration)?

I recently started having to restart my development server every time I change my code. My development.rb file still has this line:
config.cache_classes = false
I tried using the debugger verify that this value has stuck around. To do this I set my configuration to a global variable in environment.rb:
$my_initializer = Rails::Initializer.run do |config|
...
end
then I put a debugger line in one of my controllers so I could do this:
(rdb:2) $my_initializer.configuration.cache_classes
false
So that eliminated the possibility that the value of cache_classes was getting set to true somewhere else. I've tried using both Mongrel and WEBrick and it still happens.
What else might be causing Rails not to reload my code with every request?
I am running:
Mongrel 1.1.5
WEBrick 1.3.1
Rails 2.3.8
Ruby 1.8.7 p253
EDIT:
at #Daemin 's suggestion I checked that the mtime of my files are are actually getting updated when I save them in my text editor (Textmate)
merced:controllers lance$ ls -l people_controller.rb
-rwxr-xr-x 1 lance staff 2153 Act 10 18:01 people_controller.rb
Then I made a change and saved the file:
merced:controllers lance$ ls -l people_controller.rb
-rwxr-xr-x# 1 lance staff 2163 Oct 11 12:03 people_controller.rb
So it's not a problem with the mtimes.
So it turns out that config.threadsafe! overwrites the effect of config.cache_classes = false, even though it doesn't actually overwrite the value of cache_classes (see my question for proof). Digging around a bit more in the Rails source code might illuminate why this might be, but I don't actually need threadsafe behavior in my development environment. Instead, I replaced my call to config.threadsafe! in environment.rb to
config.threadsafe! unless RAILS_ENV == "development"
and everything works fine now.
If anyone else has this problem the solution was the order: config.threadsafe! has to come before config.cache_classes. Reorder it like this to fix it:
...
config.threadsafe!
config.cache_classes = false
...
answer from: Rails: cache_classes => false still caches
I suspect that the classes you are expecting to refresh have been 'required' somewhere in your configuration. Note that Rails' dependency loading happens after Ruby's requires have happened. If a particular module or class has already been required, it will not be handled by Rails' dependency loader, and thus it will not be reloaded. For a detailed explanation, check out this article: http://spacevatican.org/2008/9/28/required-or-not
Despite the fact that the threadsafe! solution works, I also wanted to point out for your benefit and the others that may come in after the following...
If you're editing engine code that is directly in your vendor/engines directory, those files will not be updated without a restart. There may be a configuration option to enable such functionality. However, this is very important to remember if you have used engines to separate large bits of functionality from your application.
My guess would be that it's not reloading the classes for each request because they haven't changed between requests. So the system would note down the last modified time when the classes are loaded, and not reload them until that changed.

What does "WARN Could not determine content-length of response body." mean and how to I get rid of it?

Since upgrading to Rails 3.1 I'm seeing this warning message in my development log:
WARN Could not determine content-length of response body. Set content-length of the response or set Response#chunked = true
What does this mean and how can I remove it? Is it a problem?
Asked the same question to one of Rails-Core's members:
https://twitter.com/luislavena/status/108998968859566080
And the answer:
https://twitter.com/tenderlove/status/108999110136303617
ya, it's fine. Need to clean it up, but nothing is being hurt.
The following patch solved the problem in my case; no more warnings for me.
204_304_keep_alive.patch
Just edit the file httpresponse.rb at line 205 as shown at the link above; in fact the link shows a correction made to a future release of Ruby.
I'm using rails 3.2.0 on ruby 1.9.3-p0 installed through RVM as a single user. So the location in my case is:
~/.rvm/rubies/ruby-1.9.3-p0/lib/ruby/1.9.1/webrick/httpresponse.rb
The location of the file to be altered differs depending on the type of installation, RVM or not, or even multi-user or single user, so I'm just giving the last part of it:
.../ruby-1.9.3-p0/lib/ruby/1.9.1/webrick/httpresponse.rb
I hope this can be helpful to someone.
EDIT: This is the link to the commit that altered the line in question in the trunk branch of ruby project.
Just explicitly adding the Gem to the Gemfile got rid of the warning messages for me:
group :development do
gem 'webrick', '~> 1.3.1'
end
You can also use Thin instead of the default Webrick.
Add this to Gemfile
gem 'thin'
then rails s thin will use thin, and the warning will disappear.
If you're using .rvm, do this to fix it...
As mentioned by João Soares, all credits to him, this is what you can do if you wan't to get rid of this warning on development.
Use your favorite editor to open this file:
~/.rvm/rubies/<ruby-version>/lib/ruby/1.9.1/webrick/httpresponse.rb
Go to the line that contains this(for me it was really line 206):
if chunked? || #header['content-length']
Change it, taken from this patch, to this:
if chunked? || #header['content-length'] || #status == 304 || #status == 204
Save the file and eventually restart your rails server
This problem has been fixed in Ruby's trunk branch with this commit to webrick.
You can edit this particular webrick file similarly in your setup. The approximate location can be found by:
gem which webrick
To actually edit the file:
nano \`ruby -e"print %x{gem which webrick}.chomp %Q{.rb\n}"\`/httpresponse.rb
(Or instead of nano, use your favorite editor.)
JRuby version: If you're using .rvm, do this to fix it...
As mentioned by João Soares and Kjellski, this is what you can do if you want to get rid of this warning on development and you are using JRuby.
Use your favorite editor to open this file:
~/.rvm/rubies/jruby-<version>/lib/ruby/<1.8 or 1.9>/webrick/httpresponse.rb
Go to the line that contains this (for me it was line 205):
if chunked? || #header['content-length']
Change it, taken from this patch, to this:
if chunked? || #header['content-length'] || #status == 304 || #status == 204
Save the file and eventually restart your rails server.
Another workaround that removes the offending line from webrick. It's just not that useful:
cd `which ruby`/../../lib/ruby/1.9.1/webrick/ && sed -i '.bak' -e'/logger.warn/d' httpresponse.rb
(you may need to sudo)
Add
config.middleware.use Rack::ContentLength
to your application.rb file, and the warning will disappear even with webrick. This will also set Content-Length properly in production when rendering a json or text response.

How can I use option "--bare" in Rails 3.1 for CoffeeScript?

Someone know how can I use this option in Rails 3.1?
Now CoffeScript puts a function with .call(this) on each file, but I want to remove this.
EDIT:
"Can't find variable” error with Rails 3.1 and Coffeescript" and "Pattern for CoffeeScript modules" have what I want. I'll change my global vars to use #global scope.
I'd recommend against doing this. See my answer at Pattern for CoffeeScript modules for some of the reasons why. ("Making your CoffeeScript code incompatible with out-of-the-box Rails 3.1" is yet another reason.) Better to just use
window.a = b
or even
#a = b
instead of a = b when you're trying to export something to global scope.
In previous versions of Rails 3.1, bare compilation was enabled. This was classified as a bug, and fixed in RC1.
So while I strongly encourage you not to do this, here's how to turn bare compilation back on: Add
Tilt::CoffeeScriptTemplate.default_bare = true
to your environment.rb.
I do recommend taking advantage of CoffeeScript's closures and following a CommonJS module patter. But sometimes, just sometimes, it is OK to want to use the --bare option. In my case, when rendering a Jasmine spec helper so I could keep things at the top level and also take advantage of the include Sprockets directive in said Jasmine specs.
To that end, I created the "sprockets-blackcoffee" gem, which you can learn about here. https://github.com/metaskills/sprockets-blackcoffee

Resources