Packaging

One of the awesome features of Interleave is that is can be used to generate different module specific (CommonJS, AMD, etc) versions of your library from a single source file. This is not the default functionality of Interleave, but can be enabled by specifying a --wrap option when running your build.

One of the primary reasons to consider using Interleave’s packaging is to enable to reuse other library code without having to get stressed about implementing module specific require, define, etc calls to include the required libraries. This is something that Interleave will take care of for you in the packaged files.

To specify a dependency, you can simply use the FindMe module requirement syntax:

// req: underscore as _

or to request a particular version:

// req: underscore 1.3.x as _

A Packaging Example

Let’s work through a small, somewhat contrived example of a library that is designed for ‘fonging’ (a term from the movie A Knight’s Tale). Now, fong.js is going to need underscore to operate correctly, so we’ll need to include a // req: comment:

// req: underscore as _
function fong(crowd) {
	// find valid, fongable targets
	var targets = _.filter(crowd, function(target) {
		return (target.name === 'Chaucer' || target.annoying) &&
			typeof target.kick == 'function';
	});

	// kick each of the valid targets
	_.invoke(targets, 'kick');

	// return the kicked targets
	return targets;
}

While this is an extremely trival and contrived example it helps to demonstrate a few key points:

  • There are no CommonJS require statements in the library to include underscore.
  • There are no export mechanisms (globbing, module.exports or AMD define) to expose the functionality of this module.
  • The code is not wrapped in a closure, thus you might think the generated code would horribly pollute the global scope (in a more complicated example).

Building our Packages

Building our appropriately packaged, distribution files is very simple:

interleave build src/*.js --wrap

Using the --wrap option with no arguments instructs Interleave that you want to generate packages for the common package types (amd, commonjs and glob). If you would like to generate only some of these package types you can specify --wrap=amd,commonjs or something similar.

AMD

define('fong', ['underscore'], function(_) {
    function fong(crowd) {
    	// find valid, fongable targets
    	var targets = _.filter(crowd, function(target) {
    		return (target.name === 'Chaucer' || target.annoying) &&
    			typeof target.kick == 'function';
    	});
    
    	// kick each of the valid targets
    	_.invoke(targets, 'kick');
    
    	// return the kicked targets
    	return targets;
    }
    
    return typeof fong != 'undefined' ? fong : undefined;
});

CommonJS (Node)

var _ = require('underscore');

function fong(crowd) {
	// find valid, fongable targets
	var targets = _.filter(crowd, function(target) {
		return (target.name === 'Chaucer' || target.annoying) &&
			typeof target.kick == 'function';
	});

	// kick each of the valid targets
	_.invoke(targets, 'kick');

	// return the kicked targets
	return targets;
}

if (typeof fong != 'undefined') {
    module.exports = fong;
}

Globbing

// req: underscore as _
(function(glob) {
    function fong(crowd) {
    	// find valid, fongable targets
    	var targets = _.filter(crowd, function(target) {
    		return (target.name === 'Chaucer' || target.annoying) &&
    			typeof target.kick == 'function';
    	});
    
    	// kick each of the valid targets
    	_.invoke(targets, 'kick');
    
    	// return the kicked targets
    	return targets;
    }
    
    if (typeof fong != 'undefined') {
        glob.fong = fong;
    }
}(this));