documentcloud / jammit

Industrial Strength Asset Packaging for Rails
http://documentcloud.github.io/jammit/
MIT License
1.16k stars 197 forks source link

environment specific settings and turning off JS compression #12

Closed agibralter closed 14 years ago

agibralter commented 14 years ago

Would it make sense to have an option to skip compression in the development environment?

documentcloud commented 14 years ago

You can actually already do this, but it's not documented. When Java is unavailable, Jammit will run in a degraded mode where assets will be packaged but not compressed. Like earlier -- I don't want to encourage this in development because it makes it harder to debug your JS when it's packaged. But for your special case, add this to assets.yml, and you'll get the behavior you want:

compressor_options:
  disabled: true
agibralter commented 14 years ago

hmm that seems to give me YUI::Compressor::OptionError => undefined option :disabled

agibralter commented 14 years ago

Also, on the flip side, it's hard to debug JS when it's compressed and firebug tells me something like, "h is null" on line 1 (where line 1 is all of my JS code)...

documentcloud commented 14 years ago

Thanks for the bug report. The test was using the Closure Compiler, not YUI. But the option should be cleaner in any case. I've just pushed a commit to master that makes disabling compression a first class option. Grab it, build the gem for yourself, and then in assets.yml:

compress_assets: off

Precisely because it's hard to debug JS when the JS is all obfuscated, is the reason why it's recommended to allow Jammit to keep it's default behavior, and serve up unpackaged assets in development.

agibralter commented 14 years ago

I haven't had a chance to test the patch -- will do so later today.

However, back on the subject of development and debugging, it sounds like your last comment supports my original point: Jammit's default behavior is to write out a separate script tag for every item in a package. How is this any different from concatenating all the JS files in a package into one single file? Without compression/obfuscation, these two methods should exhibit the exact same behavior. I would advocate for the development behavior to be to "package"/combine the JS files but to not compress/obfuscate them. Although this would still be slightly slower than Jammit's current behavior, it would be much speedier than compressing I imagine; also, this gives the added benefit of being able to keep JS files anywhere in the Rails project directory without having to symlink from somewhere in public/. I have opted to keep un-compiled/un-obfuscated JS files in app/javascripts, and this goes nicely with my app/stylesheets directory that compass uses.

documentcloud commented 14 years ago

This is a good discussion to have on the record. If you'd like to keep your JS somewhere else in your app, I'd recommend symlinking to it from public. The reason why Jammit writes out the script tags individually is because you need the separate files in order to effectively debug your JS and CSS. When you're using Firebug or the WebKit inspector, and you're looking at a CSS rule, or JS throws an exception, you get the file name and line number of the corresponding code. If you concatenate files, the file name and line number are rendered meaningless. It's important not to alter the source files in any way while developing: no compression, no concatenation.

agibralter commented 14 years ago

Alright, I'm starting to come around to your way of thinking... :)

For the record, though, most of the debugging tools like Firebug and WebKit's inspector show you the code inline... but yeah, then it can be a little bit of a hassel to go and find it in the un-packaged code... alright I'm sold.

Thanks for fleshing this out with me -- and it's definitely good to have it on record.

Oh and I also tested your compress_assets: off patch and it seems to work... but I do think I'll take the symlink path now.

agibralter commented 14 years ago

Actually, how do you suggest I do the symlinks?

Jammit is producing tags that look like this now:

<script src="/app/javascripts/vendor/jquery-1.3.2.min.js" type="text/javascript"></script>

Should I symlink to my app directory in public? I guess that's not so bad as long as it is only in development mode... but it does seem like Jammit has some tricks up its sleeve in that it removes the '/public' if you point to a JS asset that is acutally in /public.

documentcloud commented 14 years ago

Jammit works with Rails' public directory by convention. I would do something along these lines:

cd public
ln -s ../app/javascripts javascripts

And then, in your asset packager:

public/javascripts/vendor/*.js
agibralter commented 14 years ago

Ah, I was thinking of a different approach:

cd public; ln -s ../app app

And then in assets.yml:

app/javascripts/vendor/*.js

And in .gitignore: public/app

This way the production server only reveals compressed, obfuscated JS... I guess that's mean and un-opensource-y of me... but I'll probably use other means of publishing un-obfuscated code that I want to share with the world (github FTW).

documentcloud commented 14 years ago

That'll work too, you just need to make your assets.yml entry look like:

public/app/javascripts/vendor/*.js

All asset package references are relative to RAILS_ROOT.

agibralter commented 14 years ago

I know -- but public/app won't exist when I deploy my app since it's in gitignore and I don't want people reading my ruby source :). That's why I have:

javascripts:
  main:
    - app/javascripts/vendor/jquery-1.3.2.min.js
    - app/javascripts/vendor/json2.js
    - app/javascripts/vendor/jquery-plugins/*.js
    - ...

in my assets.yml.

agibralter commented 14 years ago

Just for the record, here is my setup, including my development.rb snippet that does the sym-linking automatically: http://gist.github.com/254581