While JS is not a compiled language, my personal preference is to use a build process to construct even fairly simple libraries. While there are some exceptions, the following illustrates the general directory structure of most of my JS libraries:
dist/
commonjs/fong.js
amd/fong.js
glob/fong.js
src/
fong.js
test/
README.md
Makefile
package.json
The entire dist/ folder is generated through a build process, and should not be edited by hand. Rather files in the src/ directory are those which should be updated by package authors. While using this approach does create some confusion on which file(s) a potential contributor should edit if they wish to fork the library (definitely a downside of this approach) hopefully this documentation should help explain why the approach is used.
Using Interleave we can write our source files in a completely package agnositic way. For example, let’s assume that our fong library (as per the movie A Knight’s Tale), is going to require underscore to operate correctly.
To achieve this we supply a simple dep or req comment:
// req: underscore as _
Interally, Interleave uses the findme module requirement syntax which is it then translates into module specific outputs for the various distrubutions. Let’s carry on - time to make fong actually do something.
Our fong library is very simple, and will simply call a kick method on any valid targets in a crowd (array) of people. Here’s the code for the entire source file:
// 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:
Building our distribution files is very simple if you have Interleave installed, and if not you can install it by installing it using NPM:
(sudo) npm install interleave -g
Once you have Interleave installed, simply jump into the examples/fong directory and run the following command in your console:
interleave build src/*.js --wrap
The –wrap option tells Interleave that we want it to provide platform specific variants of our input source file. The resulting files from running this process is shown below and can be found in the repository in the examples/fong/dist folder.
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;
}
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;
});
// 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));
Feedback related to this page would definitely be appreciated and can be captured at the following url:
https://github.com/DamonOehlman/reusable-javascript/issues/1