less / more

less on rails — the official LESS plugin for Ruby on Rails
http://lesscss.org
MIT License
226 stars 41 forks source link

not parsing .less files on each request in development. only on initialization. #14

Closed jonbuda closed 14 years ago

jonbuda commented 14 years ago

Just attempted to transition from less-on-rails to to more...and it's not exactly working in development. it does generate the css files upon initialization, but each following request does not regenerate the .css files. it does remove them though, so all I see is unstyled html.

I don't think I'm doing anything out of the ordinary. using all the default settings and the less 1.1.13 gem.

KieranP commented 14 years ago

I got the same problems too. I fixed it by doing this:

http://github.com/KieranP/more/commit/2f9065491f17c6a76f337b26311241118a8f1b95

Hopefully this commit will get pulled in ASAP. More is broken!

augustl commented 14 years ago

The whole idea is to have the CSS generated by the controller, but that won't work with a stylesheet_link_tag ..., :cache => true because Rails tries to read the css files before the controllers gets to them. And the controller won't get to them anyway, because of the 'all.css' file name - the individual css file(s) won't be referenced at all.

So, I won't accept a solution that generates the CSS in a before filter. I think the best solution is to only call Less::More.parse if caching is enabled.

graysky commented 14 years ago

We're seeing the same issue in development mode where the less file is only parsed at app start and not on every page request as expected. We use stylesheet_link_tag with caching, but that isn't applicable to the dev mode problem.

The exception I see when looking at the "foo.css" link is:

ArgumentError in Less cacheController#show

"A copy of ApplicationController has been removed from the module tree but is still active!"

I'll take a look at KierenP's patch because right now More is busted in development.

augustl commented 14 years ago

I am not able to reproduce this issue. I created a rails app, installed the plugin, created a .less sheet, and no files were generated when I booted the app. Visiting /stylesheets/xxx.css hits the controller. Everything seems to work correctly.

Can one of you post the steps necessary to reproduce this issue?

@graysky: are you using a old rails version? I don't get any error messages when visiting the stylesheets controller in dev mode.

KieranP commented 14 years ago

augustl, I see. I misunderstood more's usage. However..... many users probably think how I thought and believe that the CSS should be generated on app startup and on every page request, in development.

And by the way, I don't use caching on my stylesheets and it's still broken.

<%= stylesheet_link_tag 'application', 'weekly', :media => 'screen' %>

I have an application.less in the Less::More.source_path. When I start my app, and hit the front page, all I get is html, no css what-so-ever. Shouldn't have to hit a controller to get the CSS prepped

I'm using Rails 2.3.4 by the way, and the patch I posted above fixes all issues I was getting. It acts the same way in production mode, but works as everyone else expects in development mode.

augustl commented 14 years ago

You have to hit a controller to generate the CSS, because it's the controller that actually serves it. You won't have to access it by hand or anything. A stylesheet_link_tag "foo" will cause a hit on /stylesheets/foo.css, which matches the route of the less controller, serving the CSS dynamically.

I'm not sure what causes this to not happen in your environment. Again, it would be very nice if you could reproduce the error and post a list of steps I need to take in order to reproduce it, so that it is possible for me to identify the bug.

graysky commented 14 years ago

In our template we use:

<%= stylesheet_link_tag "reset", "foo", :cache => "bundle" %>

and are on Rails 2.3.2. In dev mode the bundle is not in effect. The 1st request works, and then it barfs. Putting in the hack fixes the problem.

augustl commented 14 years ago

I need steps :) Here's the steps I take when I try to reproduce the error. Everything works nicely when I do the following:

augustl@honk ~/Desktop> rails foo

  ... generator output ...

augustl@honk ~/Desktop> cd foo
augustl@honk ~/D/foo> ./script/plugin install git://github.com/cloudhead/more.git

  ... installer output ...

augustl@honk ~/D/foo> mate app/stylesheets/screen.less

  Adding this to it: body { background:#999; }

augustl@honk ~/D/foo> ./script/generate controller test

  ... generator output ...

augustl@honk ~/D/foo> mate app/views/test/index.html.erb

  Content:

  <html>
    <head>
      <%= stylesheet_link_tag "screen" %>
    </head>
    <body>Test</body>
  </html>

augustl@honk ~/D/foo> mate config/routes.rb

  Content:

  ActionController::Routing::Routes.draw do |map|
    map.connect 'test', :controller => 'test'
  end

augustl@honk ~/D/foo> ./script/server

When I visit http://localhost:3000/test, I get a grey background. No file has been generated in public/stylesheets. I don't have to visit the stylesheets controller directly, it works on the first request. Subsequent requests works without problems. If I change the .less file, the generated CSS changes too. I can use multiple .less files, e.g. <%= stylesheet_link_tag "screen", "test", :cache => "bundle" %> works as expected for me in development mode (no bundle.css has been generated in public/stylesheets, and so on).

Please post the steps necessary to reproduce the issues you are having; I am not able to do so myself, as you can see from the above.

jonbuda commented 14 years ago

This is totally weird. I also just created a new app from scratch similar to how you did it and it appears to be working as it should. However when I replace less-for-rails with more in an existing app it does not...I'll have to investigate further.

augustl commented 14 years ago

less-for-rails, my old plugin, looks for .less files in public/stylesheets, while the more plugin looks in app/stylesheets. Either set Less::More.source_path = RAILS_ROOT + "/public/stylesheets", or move the .less files to app/stylesheets.

Was this the issue at hand? Can the other posters in here confirm a similar issue and result?

KieranP commented 14 years ago

I cam over from less-for-rails, but I have my source_path set to /public/stylesheets already and still it doesn't work.

augustl commented 14 years ago

@KieranP: OK, so there is apparently another issue as well. However, as you can see from my earlier post, I am not able to reproduce this bug. Unless you can provide a formula for reproducing the issue you're having, there's nothing I can do to fix it.

graysky commented 14 years ago

I fixed my problem by adding "unloadable" to the LessCacheController to solve error messages about "ApplicationController has been removed from the module tree error." Tip was found here: http://nerbie69.blogspot.com/2008/12/solved-applicationcontroller-has-been.html

That stopped the error where it would blow up on the 2nd request. I'm using Rails 2.3.4 and saw that another Rails Engine we're using (HighVoltage by Thoughtbot) has the same unloadable line in their controller that subclasses ApplicationController.

Thanks for the help and sorry I haven't had time to post more detailed steps.

KieranP commented 14 years ago

Ok, I tracked down the issue (sorry it took so long). When in app/stylesheets, everything worked fine, only public/stylesheets was failing. Turns out Less::More.exists? was false so the controller returned nothing. It was false because Pathname.glob (which in turn calls Dir.glob) does weird things when passed a pathname, rather than a string. Got around this by changing the pathname_from_array method in lib/more.rb to pass in a string from File.join.

-      Pathname.glob(self.source_path.join(*path_spec))[0]
+      Pathname.glob(File.join(Rails.root, self.source_path.to_s, *path_spec))[0]

Using the above fix, everything is working nicely again in development and production modes without any other hacks above.

augustl commented 14 years ago

Awesome! If you want to do the honors, feel free to fork and submit a pull request :)

augustl commented 14 years ago

Fixed in http://github.com/cloudhead/more/commit/74e6b52c6cce67f24f92df799233d723e4ec74c3.

Post a comment here if this issue hasn't been resolved.

jonbuda commented 14 years ago

I just reinstalled the plugin, and I'm still having the same issues in development. CSS is generated on the first app load, then nothing on subsequent requests.

augustl commented 14 years ago

@jonbuda: Please post the steps I need to take in order to reproduce the error you're getting. If you scroll up, you can see that I have posted the steps I took when trying to reproduce this error, but I was unable to.

jonbuda commented 14 years ago

Ok, so when I create a fresh rails app everything is seems to be working ok. When I try to install the more plugin in an existing app, it's not working ok. I did notice that when I tried to go directly to a .css file, I received the error:

A copy of ApplicationController has been removed from the module tree but is still active!

I think what's happening is that the authlogic gem and the more plugin are causing this to happen. I did find a fix for it, but it seems rather hackish. in my environment.rb file I added the line:

config.reload_plugins = true if RAILS_ENV == 'development'

now it's all working just fine.

Another thing I noticed when comparing more to the less-for-rails plugin is that it's SLOW in development. Whereas less-for-rails compiled the .less files into .css only if they changed, it seems like more compiles them in memory on every page load in development? for larger sites with large stylesheets it's incredibly slow and incredibly hard to work with. I realize it's development, but is there any way to speed it up or cache it so that the css is generated only is .less files change?

i'll probably just stick with the old plugin for now.

KieranP commented 14 years ago

augustl & jonbuda: You might apply the change mentioned by graysky above.

http://github.com/cloudhead/more/issues/closed/#issue/14/comment/57524

Unloadable should fix the "removed from module tree" issues.

graysky commented 14 years ago

I wonder if this might be related to having other plugins/engines installed? @augustl has been great at trying to repro this, but it doesn't seem to pop up in a clean install.

Also, I've noticed that the More plugin feels slower than the less-is-rails. Does it look at the mod time on the .less file to decide if it needs to regenerate the .css?

jonbuda commented 14 years ago

yeah, I'm pretty sure it's a conflict with other plugins, namely 'authlogic' in my case.

robotmay commented 14 years ago

I'm also getting this problem, and I too have AuthLogic installed. Any progress?

augustl commented 14 years ago

No progress.

If ppl have confirmed that you only need to add one statement in a controller, I'm happily accepting a pull request :)

rapind commented 14 years ago

I think there were some other bugs reported in this thread, but the original bug at least seems to fixed. May want to close this one out. The slowness in dev mode has also been fixed by caching in the tmp dir (caching in the public/stylsheets dir which I think people were trying to do before, won't work because rails routing won't kick in to serve stylesheets and compare mtimes... thus never updating the cache with your changes).

augustl commented 14 years ago

Allright, closing.