= Jake
Jake is a command-line line tool for building JavaScript packages from source code. It's basically a thin wrapper around {Packr}[http://rubygems.org/gems/packr] that lets you easily configure builds for multiple packages with different compression settings, using a simple YAML config file.
It supports all the same compression settings as Packr, including generation of {source maps}[http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/] for your package files. You can also use ERB in your source files to generate code.
== Usage
To begin with, create a file called jake.yml in the root directory of your project; you will run the +jake+ command from here. A basic config looks like this:
source_directory: source build_directory: build
layout: together
header: COPYRIGHT
builds: src: minify: false min: shrink_vars: true private: true
packages: [ DESCRIBED BELOW ]
=== Build listing
The build listing, given by the +builds+ option in the config file, lists all the builds you want to produce for distribution, and what minification settings each build should use. JavaScript projects typically distribute both compressed and uncompressed copies of their code to suit both production and development environments.
You can have as many builds as you like and the names are up to you. I'm using +src+ and +min+ as readily understood examples. Each build may specify some combination of the following options:
=== Package listing
The package listing, given under the +packages+ config option, describes the packages you want to produce and which source files are used to generate them. A package is named using the path under +build_directory+ where it should be generated, e.g. foo or ext/awesome (you may omit the .js extension). Each package lists one or more source files used to build it, and may optionally list some extra options as described below.
For the examples, assume the source directory is +src+ and the build directory is +dist+. This package uses a single source file src/foo.js and generates dist/foo_dist.js:
foo_dist: foo
This package generates dist/bar.js from src/bar1.js and src/bar2.js
bar: - bar1 - bar2
This generates a package at dist/sub/dir.js from src/path/file.js and src/path/baz.js:
sub/dir: - path/file - path/baz
If all the source files for a package live in the same subdirectory, you can tidy things up using the +directory+ option. If you use any package-level options, you must list the files under the +files+ option (the above examples are just syntactic shorthands for this):
sub/dir: directory: path files: - file - baz
The full list of package options is as follows:
For example, here's a package listing that uses all the options:
packages: foo_dist: foo
bar:
- bar1
- bar2
sub/whizz:
extends: foo_dist
directory: path
header: CUSTOM_HEADER
files:
- file1
- file2
last:
packer:
private: false
meta:
requires:
- jQuery
- GMap2
files:
- one_file
- another_file
In conjunction with the build options listed above, this matches the following project layout (omitting build name suffixes for brevity):
=== Using ERB in source files
Jake lets you use Ruby's ERB templating system within your source code so you can insert values generated from Ruby functions. To use this feature, you need to create a file called Jakefile in the root of your project. This contains helper functions that are called in your source code to inject data.
For example, say you want to extract a version number from your version control system and inject it into your code along with the build name. Your source code should contain something like this:
MyJavaScriptLib.VERSION = "<%= version %>-<%= build %>";
And your Jakefile should contain a helper called +version+:
jake_helper :version do # extract version number from svn, git, whatever # e.g. return '1.0' end
Jake has a built-in helper called +build+ that returns the current build name. When built, the output would contain the following:
MyJavaScriptLib.VERSION = "1.0-src"; // or "1.0-min" for the 'min' build
=== Event hooks
The +Jakefile+ may also define event hooks that are fired during a build when interesting things happen. This allows you to extend your build process using configuration data from Jake. All event callbacks are passed a +Build+ object as the first argument, and may receive additional arguments depending on the event type. We currently have two events:
+file_created+ is fired whenever a new build file is created. The callback is passed the +Buildable+ package object, the current build type (+src+ or +min+ using the above examples), and the full path to the newly created file. The package object may contain metadata (set using the +meta+ option, see above) which you can use for further code generation.
+build_complete+ is fired after a build has finished running, that is after all sets of minification options have been run. At this point you can use any metadata you've gathered to generate more code, copy files to your distribution directory, etc.
$register = {}
jake_hook :file_created do |build, pkg, build_type, path| $register[path] = pkg.meta end
jake_hook :build_complete do |build| FileUtils.cp 'README', build.build_directory + '/README' # generate code from $register end
== License
(The MIT License)
Copyright (c) 2008-2012 James Coglan
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.