Jzip

A Rails gem (and also plugin) for Javascript merging and compression within Rails Apps

Introduction

Jzip was created due to the need of simply merging and minifying Javascript files to reduce HTTP requests and file size of my assets. Using sprites for images and SASS for stylesheets only left javascripts not be optimized. AssetPackager almost suited the solution, but I wanted more flexibility in configuration. So I got inspired by AssetPackager and SASS to come up with the Jzip. At first Jzip was a plugin only, but after refactoring the entire code base Jzip is available as a gem hosted on gemcutter.

Installation

Using Jzip as gem

Add gemcutter as a gem source, if you haven’t already done it:


  sudo gem sources -a http://gemcutter.org/

Install the Jzip gem:


  sudo gem install jzip

Add Jzip in environment.rb as a gem dependency:


  config.gem "jzip"

Optionally, you can run rake jzip:assets:install which creates the following:

  • assets/jzip – which is the default template location
  • assets/jzip/defaults.jz – a Jzip template which requires the default Javascript files (Prototype, Scriptaculous sources and application.js)

Using Jzip as plugin

Install the Jzip plugin:


  ./script/plugin install git://github.com/archan937/jzip.git 

Note: a Jzip template (assets/jzip/defaults.jz) for the Prototype and Scriptaculous sources along with application.js will be created

Usage

Including generated Javascript files

Just use the javascript_include_tag helper method (e.g. for the defaults.jz template):


  <%= javascript_include_tag "defaults" %>

Creating Jzip templates / partials

A .jz file (Jzip template or partial) is nothing more than a common .js file in which you can require other files for merging. You can do this by simply adding the following:


  //= require < path_to_file or path_to_template or path_to_partial or predefined_set >

Just like in Rails views and in SASS, Jzip has partials of which the output file will not be created in the target directory. The path to the Javascript file or Jzip template or partial has to be relative to the Jzip template / partial itself. Please note that specifying a preleading / in the path will be interpreted by Jzip as RAILS_ROOT/public/javascripts (which is very handy).

Other than the path to a Javascript file, you can also refer to a predefined set of Javascripts sources. At the moment, only defaults is available for the Prototype and Scriptaculous libs and application.js which are shipped with a Rails application. Any suggestions for other predefined sets are welcome.

The following instructs Jzip to merge the Prototype and Scriptaculous libraries with three custom Javascript files into public/javascripts/foo.js:

Note: template is located in assets/jzip/foo.jz


  //= require shared/top_up
  //= require /defaults
  //= require builder/module
  //= require builder/model_browser

Registering template locations

You probably already have guessed that the default location for Jzip templates is RAILS_ROOT/assets/jzip. I can imagine that you would have choosen another location. So fortunately, the Jzip engine offers you to that piece of freedom. All you have to do is put the following in your environment.rb file:


  Jzip::Engine.add_template_location < your_own_template_location(s) >

This comes in very handy when building a Rails plugin that uses Jzip because you don’t want to copy your all Jzip templates to RAILS_ROOT/assets/jzip. So let’s say your plugin is called betty, all you have to do is put the following in it’s init.rb file:


  Jzip::Engine.add_template_location RAILS_ROOT + "vendor/plugins/betty/assets/jzip"

Now isn’t that a piece cake? Not only can you pass a string containing the template location, you can also pass an array of strings (containing multiple locations) or a hash (which also specifies the output directory):

  • string – target directory will be public/javascripts

  RAILS_ROOT + "/lib/jzip
  • array – target directory will be public/javascripts

  [RAILS_ROOT + "/some/path/jzip", RAILS_ROOT + "/vendor/plugins/foo/assets/jzip"]
  • hash – target directory will be public/javascripts/betty

  {RAILS_ROOT + "/vendor/plugins/betty/assets/jzip" => RAILS_ROOT + "/public/javascripts/betty"}

Compile options

Finally, Jzip has some options that you can configure in the environment.rb file:

  • :minify – Minify the merged Javascript file using the JSMin library (default: true when in production environment)
  • :always_update – Merge (and minify when specified) the Jzip templates on every page request when outdated (default: true when not in production environment)

You can specify a Jzip option by putting the following in your environment.rb file:


  Jzip::Engine.options[:minify]        = false
  Jzip::Engine.options[:always_update] = true

Contact me

For support, remarks and requests please mail me at [email protected].

Credit

This Rails engine is inspired by:

AssetPackager
http://github.com/sbecker/asset_packager/tree/master

SASS
http://sass-lang.com

Also, the Jzip engine makes use of the Ruby JavaScript Minifier created by Douglas Crockford
http://www.crockford.com/javascript/jsmin.html

ToDo’s

None.

License

Copyright © 2010 Paul Engel, released under the MIT license

http://holder.nlhttp://codehero.eshttp://gettopup.comhttp://twitter.com/archan937[email protected]

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.