Sometimes organizing frontend assets can be pretty hard. Lets say you have a bunch of
core js libraries you want to include on every page. On the admin pages of your site, you
also want to include another collection of JavaScript and CSS files. You want to
minify/compress your code for production, run with uncompressed files in dev,
and not have to think about it.
Rails and django both have the asset pipeline. At AdRoll we’re still on pylons and we didn’t want to
retrofit the django solution.
So I wrote scriptb.
scriptb is a small wrapper around The Goog’s closure compiler and Yahoo’s YUI compressor that
accepts a configuration file explaining how to organize your modules. To solve module inclusion
depending on dev or production, the scriptb configuration file can be pretty tightly integrated
into your web framework. I’ll show you integration in a second. First, the configuration.
Scriptb Coniguration
With the configuration file, you explicitly specify which files are in which modules, and their
ordering.
Create a python file somewhere in your project. scriptb works with python only as it loads a
python configuration file. This config file needs to be somewhere on the python path. Format is
as follows.
First, you’ll need to install java, google’s
Closure Compiler, and
YUI Compressor.
Then you need to create some environment variables for their paths:
Now run it. It will use the closure compiler for JavaScript, and YUI Compressor for CSS.
Make sure you have built files where you specified.
Integrating with your web framework
My main requirement was to be able to call some kind of require(list, of, module, names)
function in my templates and have all the right stuff included. I’ve only integrated this into
pylons, so this is pretty mako specific.
First I created a template called require.html with a couple functions:
Note that the previous code makes reference to c.is_production. In my base controller, I read
a config param called is_production from the ini passed into paster and put it in
c.is_production.
And now, in my templates I can include that template and just call require().