= Rake::Pipeline
Rake::Pipeline is a system for packaging assets for deployment to the
web. It uses Rake under the hood for dependency management and updating
output files based on input changes.
= Usage
The easiest way to use Rake::Pipeline is via an +Assetfile+ file in the
root of your project.
A sample +Assetfile+ looks like this:
!!!ruby
output "public"
input "assets" do
# this block will take all JS inputs, wrap them in a closure,
# add some additional metadata, and concatenate them all into
# application.scripts.js.
match "*.js" do
filter ClosureWrapper
filter DataWrapper
concat "application.scripts.js"
end
# this block will take all HTML and CSS inputs, convert them
# into JavaScript
match "*/*.{html,css}" do
filter DataWrapper
concat "application.assets.js"
end
match "*.js" do
concat "application.js"
end
end
Each +input+ block defines a collection of files, and a pipeline
that transforms those files. Within each pipeline, you can specify
a series of filters to describe the transformations you'd like to
apply to the files.
= Upgrading from Previous Versions
The +Assetfile+ syntax has changed in version 0.6.0. In previous
versions, each +Assetfile+ defined a single pipeline, and +input+
statements would add input files to that pipeline. After version
0.6.0, multiple pipelines can be defined in an +Assetfile+. The
+input+ method now takes a block, and this block defines a pipeline.
This means that any +match+ blocks or filters must be defined
inside an +input+ block, and no longer at the top level. For example,
this:
!!!ruby
# Prior to 0.6.0
output "public"
input "assets"
match "**/*.js" do
concat
end
would now be written as:
!!!ruby
# After 0.6.0
output "public"
input "assets" do
match "**/*.js" do
concat
end
end
= Filters
A filter is a simple class that inherits from
{Rake::Pipeline::Filter}. A filter must implement a single
method, called +generate_output+, which takes
two parameters: a list of input files and the output file.
Both the input and output files are {Rake::Pipeline::FileWrapper} objects.
The most important methods on a {Rake::Pipeline::FileWrapper FileWrapper} are:
- {Rake::Pipeline::FileWrapper#path path}: the path of the file, relative to its input root
- {Rake::Pipeline::FileWrapper#read read}: read the contents of the file
- {Rake::Pipeline::FileWrapper#write write(string)}: write a String to the file
For example, a simple concatenation filter would look like:
!!!ruby
class ConcatFilter < Rake::Pipeline::Filter
def generate_output(inputs, output)
inputs.each do |input|
output.write input.read
end
end
end
If you had a series of input files like:
- +app/javascripts/one.js+
- +app/javascripts/two.js+
- +app/javascripts/three.js+
and you specified the +ConcatFilter+ in your
+Assetfile+ like:
!!!ruby
filter ConcatFilter, "application.js"
The filter would receive a single call to
+generate_output+ with an Array of {Rake::Pipeline::FileWrapper FileWrapper}s
representing each of the three files, and a {Rake::Pipeline::FileWrapper FileWrapper}
representing +application.js+.
== Binary Data
If your filter is operating on binary data, like images,
rather than textual data, like source code, you can specify
that in your filter:
!!!ruby
class ConcatFilter < Rake::Pipeline::Filter
processes_binary_files
def generate_output(inputs, output)
inputs.each do |input|
output.write input.read
end
end
end
This will stop Rake::Pipeline
from trying to interpret the
input files as UTF-8
, which obviously will not work on
binary data.
= Filters
+Rake::Pipeline+ comes with a built-in filter,
{Rake::Pipeline::ConcatFilter}. Its implementation is the same as the
+ConcatFilter+ above. Other filters that are useful for web development
like a +CoffeeScriptFilter+ and +SassFilter+ are available in
rake-pipeline-web-filters.
= Preview Server
To start up the preview server, run +rakep server+. This will start up
a server that automatically recompiles files for you on the fly
and serves up the files you need.
This should allow you to have a single index.html file pointing
at the same files in both development and production.
= Compiling Assets
To compile all assets before deployment, simply run:
$ rakep build
= Encodings
If a filter does not specify that it processes binary files,
+Rake::Pipeline+ will open all inputs and outputs as +UTF-8+.
This means that if you have files encoded in other encodings,
like +Latin-1+, +Rake::Pipeline+ will raise an exception. In
this situation, you need to open the offending file in your
text editor and re-save it as +UTF-8+.
= Public Release Requirement
Before publicly releasing this code, we need to properly support
encodings other than UTF-8. That means using the
+default_external+ instead of hardcoding to UTF-8 and
providing a mechanism for specifying the encoding of a file using
a magic comment.