Node Roundup: 0.6.8 and 0.7.1, Summit Coverage, Connect Router, Mongolian DeadBeef, AWS

25 Jan 2012 | By Alex Young | Comments | Tags node modules express middleware mongo amazon
You can send in your Node projects for review through our contact form or @dailyjs.

Node 0.6.8 and 0.7.1

Node 0.6.8 is out. V8 and npm are both updated in this release, and there are also numerous bug fixes including one for the cluster module and another for fs.stat in Windows.

Meanwhile, the unstable branch has been updated to Node 0.7.1. I noticed that this brings V8 up to 3.8.8 which is the latest version in the V8 Changelog.

Node Summit Coverage

This week is the Node Summit, and David Herron has been writing up some detailed coverage at nodejs.davidherron.com/. This includes talks from Microsoft, Yahoo, VMWare, and Heroku, so it’s interesting stuff for anyone interested in Node, the cloud, and the near future of Node development.

Node is a great fit for some applications, a terrible fit for others. There’s a danger in the Node excitement to try and use Node to solve every problem. Hence, PAAS needs to be polyglot.

From Node.js Summit: Platform as a Service.

 Connect Router

Connect Router syntax diagram

Connect Router (License: MIT, npm: connect-router) by Craig Condon is a unique take on routing in Express by using strings to express relationships between routes, HTTP methods, and middleware. Routes can be loaded from a file or directory, making splitting up applications into logical groupings extremely easy.

The basic API looks like this:

app.use(connectRouter(function(router) {
  router.on('parseBody', express.bodyParser());

  router.on('user/exists', function(req, res, next) {
    if (userExists(req.query.username)) {
      res.send('That username already exists');
      return;
    }
    next();
  });

  router.on('-method=POST parseBody -> user/exists -> signup', function(req, res, next) {
    res.send('Successfuly signed up ');
  });
}));

Notice that existing Express middleware can be applied to a router – in this case bodyParser has been used.

Rather than using an API based around HTTP verbs, Craig’s routers look like EventEmitter objects, and use a DSL to define what HTTP verbs should be applied. Middleware can be triggered by listing it like this: 'user/exists -> signup'. Middleware can also be greedy, which is a convenient way of applying permissions to sets of routes.

Mongolian DeadBeef

Have you always wanted a Node MongoDB driver that has the same API as MongoDB’s shell? It seems so obvious, yet it’s tantalizingly hard to find such a module. Oleg Podsechin said he’s been using Mongolian DeadBeef (License: zlib, npm: mongolian) by Marcello Bastéa-Forte and it looks like it does the job admirably. It even includes GridFS support using streams.

Collections can be accessed using db.collection(), and then records can be found and inserted with familiar methods like collection.insert(), collection.findOne(), and collection.find. It allows queries to be built up using chains, like this: collection.find().limit(5).sort({ created: 1 }).

Amazon Web Services Node Library

It seems like Amazon are hell-bent on creating a service for everything in the universe. How can a Node hacker take advantage of this? Well, aws-lib (License: MIT, npm: aws-lib) by Mirko Kiefer is an Amazon Web Services library that provides clients for EC2, Product Advertising API, SimpleDB, SQS, SNS, SES, and ELB.

The project is dubbed as “simple” but already seems fairly extensive. Thanks to some recent Hacker News coverage it currently has 260 followers on GitHub.

jQuery Roundup: Publish Subscribe, Transparency, slabText

24 Jan 2012 | By Alex Young | Comments | Tags jquery plugins graphics text events templating
Note: You can send your plugins and articles in for review through our contact form or @dailyjs.

Publish Subscribe Plugin

Joseph Zimmerman’s Publish Subscribe Plugin (License: GPL) is an implementation of the aforementioned messaging pattern aimed at browser-based JavaScript:

var handle = $.subscribe('foo', function(topic, data) {
  console.log(data, topic);
});

$.publish('foo bar', 'This is some data');

$.unsubscribe(handle);

The author has implemented it with core jQuery methods like $.type and $.each so the source is readily understandable.

Transparency

Transparency (GitHub: leonidas / transparency, License: MIT) by Jarno Keskikangas is a template engine for jQuery that maps JSON to DOM elements using a $.render method:

var hello = {
  hello:   'Hello',
  goodbye: 'Goodbye!'
};

$('.container').render(hello);

This example would write the values to tags matching the selectors .hello and .goodbye:

Transparency relies on convention over configuration and requires you to have 1:1 match between CSS classes and JSON objects. The idea is to minimize the cognitive noise you have to deal with. Just call $('.container').render(data) and move on.

There’s a detailed blog post about Transparency here: Implementing Semantic Anti-Templating With jQuery.

slabText

slabText example

slabText (GitHub: freqdec / slabText, License: MIT/GPLv2) by Brian McAllister splits headlines into rows, and resizes them to fill the available space. This works as the browser viewport changes.

Brian notes that this is based on Erik Loyer’s slabtype algorithm, which is interesting reading for those inspired by FitText.

Gbone.js, Writing Browser Extensions, Font.js

23 Jan 2012 | By Alex Young | Comments | Tags backbone.js extensions plugins fonts

Gbone.js

Gbone.js (License: MIT) by Gobhi Theivendran is a framework built on top of Backbone.js for building mobile applications, inspired by Spine Mobile. It contains several classes that extend Backbone’s classes to make it easier to build mobile applications. For example, Gbone.Stage contains multiple Gbone.Panels, and the panels are managed internally by a panel manager. They have a default skeleton like this:

<div class="container">
  <header></header>
  <article></article>
</div>

Panels can be activated and deactivated, animated using a transition. Only one stage and panel can be active at one time, so the end result is similar to native Android and iOS interfaces.

There’s a Gbone.js demo app, which is a rewrite of currency.io. Gbone.js works with both jQuery and Zepto.

Writing Browser Extensions - Comparing Firefox, Chrome and Opera

Writing Browser Extensions - Comparing Firefox, Chrome and Opera by Parashuram Narasimhan explores writing a browser extension for multiple browsers. The author covers a lot of topics, including manifest files, background processes, message passing, and debugging.

This tutorial is based on Parashuram’s experiences writing the MediaPlus, so some of the coverage is specific to that, but it’s general enough to get a good overview of how difficult it is to support all of the major browsers with a single extension.

Font.js

Font.js (GitHub: Pomax / Font.js, License: MIT) by Mike Kamermans is a font API for client-side JavaScript. Fonts can be loaded on demand, and an onload callback will run once the font has been loaded:

var font = new Font();

font.onload = function() {
  // The new font has loaded
};

font.src = 'http://example.com/font.ttf';

Metrics for a font can be accessed. For example, font.metrics.leading will give the line height.

Flavors of JavaScript, 3D Events, LowKick

20 Jan 2012 | By Alex Young | Comments | Tags webgl graphics language ECMAScript testing

Different Flavors of JavaScript

In Different flavors of JavaScript by Lakshan Perera, ECMAScript, ES3, ES5, and ES.Next (Harmony) are explained. Lakshan gives helpful links in context, like es5.github.com, and gives hits on what browser support is available.

For related reading, I touched on some of these areas before in the History of JavaScript series.

DOM Events in 3D Space

DOM Events in 3D Space is a tutorial by Jerome Etienne that demonstrates how to use threex.domevent.js. The 3D DOM event demo shows how this works – click on each teapot and different animations will be triggered. THREE.Ray is used, in particular the intersectScene method, to determine if an event intersects an object.

Jerome has also recently published Boilerplate Builder for Three.js which allows a customised set of HTML, JavaScript, and CSS to be generated that includes everything needed to get started with three.js.

LowKick

LowKick by E. Azer Koçulu simplifies running tests in multiple JavaScript environments. For example:

./bin/lowkick command ie6 test/config.json

This example, given suitable tools, will run tests in IE using VirtualBox. Headless testing is documented in the project’s readme, but it’ll need a little bit of effort to get it working.

Other drivers can be used, or added through configuration files. For example, LowKick comes with a Node driver, VirtualBox, and “virtualbox-ie”.

Semicolons, Objectively

19 Jan 2012 | By Alex Young | Comments | Tags node style language

Last week in Programming Styles in the Node Community I discussed the styles of three prominent developers in the Node community. The ensuing debate mainly focused on semicolons. Rather than telling you my opinion on the topic, I’d like to explore it objectively so you can make your own decision on whether to use them or not.

Style and semantics aside: how are semicolons handled by minimizers? Is it safe to write a client-side library without semicolons?

Let’s look at the two most popular minimizers according to JavaScript Developer Survey 2011 Results.

YUI Compressor

YUI Compressor can be downloaded as a zip file and includes a jar file in the build/ directory that can be used like this:

java -jar yuicompressor-x.y.z.jar myfile.js -o myfile-min.js --charset utf-8

This basic usage will insert semicolons. If you write a file without semicolons, it’ll remove newlines and insert them for you. It’ll also add semicolons to the end of a file, so concatenating multiple files is safe.

Closure Compiler

Closure Compiler is also a Java application, and there’s a web interface for it at closure-compiler.appspot.com. By default semicolons are also inserted, and a semicolon will again be appended to the end of the file to aid concatenation.

In cases where usage is ambiguous, Closure Compiler will raise JSC_SUSPICIOUS_SEMICOLON. Try this in the web interface:

if (true);
else alert('no');

The Closure Error and Warning Reference documentation explains this warning, which can be turned off:

The compiler assumes that this is a mistake, and that you meant to have a statement between if (true) and the semi-colon.

Both of these libraries will also strip unnecessary semicolons. For example, given this simple example:

function hello(longName) {
  alert('Hello, ' + longName);
}
hello('New User');

The semicolon after alert will be removed.

Standards

Standard ECMA-262 and previous versions of ECMAScript include “Automatic Semicolon Insertion”:

Certain ECMAScript statements (empty statement, variable statement, expression statement, do-while statement, continue statement, break statement, return statement, and throw statement) must be terminated with semicolons. […] For convenience, however, such semicolons may be omitted from the source text in certain situations.

Prior to this edition of ECMAScript, deprecating or removing this feature was discussed by Brendan Eich and Douglas Crockford in es3.1:semicolon_insertion. Crockford said:

Strong language in a spec is not likely to work. A carrot of better features that induce rewriting works better, but nothing is predictable.

This “carrot” approach comes up frequently in the discussion of ECMAScript’s development, and it can be seen under the list of Themes in the index to the Harmony namespace at the ECMAScript Wiki: harmony:harmony.

Conclusion

When deciding on JavaScript style, the debate on whether to use semicolons will never end. Objectively we can say that:

  • The tools to write client-side code without semicolons exist and are widely used
  • The specification explains how semicolon insertion works, and even includes concrete examples
  • Semicolons are going to stay around for a while

Other languages have optional semicolons. Take Ruby for example: the community at large embraced writing code without semicolons. However, many JavaScript developers learned the language without the benefit of newer tools that help work safely without semicolons. Others are working with server-side JavaScript, running code on one platform rather than multiple browsers and meddling HTTP proxies. They’re able to embrace styles that were previously deemed “unsafe”.

The nature of the language is changing, so expect to see less semicolons in the future.

However, if you like the “machine”-like look of semicolons, and feel more comfortable expressing your intent by using them judiciously, then by all means use them!

Keep your style consistent, and enjoy writing JavaScript.

Node Roundup: 0.7, Cromag, Servitude, Magician

18 Jan 2012 | By Alex Young | Comments | Tags node modules date graphics
You can send in your Node projects for review through our contact form or @dailyjs.

Node 0.7

Node 0.7.0 was announced on the Node blog, which marks the first release of the new unstable series:

Almost all users will want to remain using the stable v0.6 releases

This version includes experimental isolates support. There’s a lot of discussion on this in the Node v0.7.0 nodejs group thread. Ben Noordhuis gave a brief overview:

Isolates are (will be) API-compatible with child processes. So you call child_process.fork({thread:true}) and it will spawn a new isolate instead a new process.

Isolates are something that will crop up a lot more as Node heads towards 0.8, so it’s worth being aware of what they are and how they work.

Cromag

Cromag (License: MIT, npm: cromag) by Jerry Sievert is named after the fact it doesn’t use monkey patching, unlike a lot of date libraries. We’ve recently seen some extremely solid date libraries, including XDate, and Cromag is another offering with a different API.

Cromag currently offers a slew of methods to manipulate dates and times, which are documented in the Cromag readme. The author has also included tests written with Vows, so it should be fairly easy to hack and patch it.

Servitude

Servitude (GitHub: JerrySievert / servitude, License: MIT/X11, npm: servitude) also by Jerry Sievert, helps inject CSS and JavaScript into the DOM to cut down on requests. It can also optionally cache requests and mangle them with Uglify.

Jerry’s examples demonstrate Servitude being used with Bricks which is his Node web framework. Servitude’s plugin signature looks similar to Connect middleware, but I don’t think Bricks uses the same API for the request and response objects.

Magician

Magician (License: MIT, npm: magician) by Vadim Demedes is an ImageMagick library. The command-line ImageMagick libraries are required, but once they’re installed lots of image manipulation tools are possible from within your Node applications.

jQuery Roundup: Jsonify, jquery-download, jqPagination

17 Jan 2012 | By Alex Young | Comments | Tags jquery plugins json pagination
Note: You can send your plugins and articles in for review through our contact form or @dailyjs.

Jsonify

Jsonify by Jorgen Horstink can serialize DOM elements into JSON through the use of HTML5 data attributes. The two attributes, data-jsonify-name and data-jsonify-getter, are used to map and process values as they’re serialized:

$.jsonify({
  getters: {
    fruit: function () {
      return this.html().toLowerCase();
    }
  }
});

Then $('form').jsonify() can be used to process a form with fields like this:

<span data-jsonify-name="food.fruit[0].name" data-jsonify-getter="fruit">Orange</span>:
<input type="checkbox" data-jsonify-name="food.fruit[0].value" value="yes"><br>

<span data-jsonify-name="food.fruit[1].name" data-jsonify-getter="fruit">Banana</span>:
<input type="checkbox" data-jsonify-name="food.fruit[1].value" value="yes"><br>

<span data-jsonify-name="food.fruit[2].name" data-jsonify-getter="fruit">Strawberry</span>:
<input type="checkbox" data-jsonify-name="food.fruit[2].value" value="yes"><br>

jquery-download

jquery-download demo

jquery-download (License: BSD, Demo: jquery-download demo) by John Krauss allows the DOM, or parts of it, to be downloaded through data: URIs. The author’s demo has some SVG, so this plugin could be used to extract and download SVG as it’s edited.

The same author has a load of new stuff on GitHub at github.com/talos.

jqPagination

jqPagination screenshot

jqPagination (GitHub: beneverard / jqPagination, License: GPL v3) by Ben Everard is a different interface for pagination: next and previous selectors are displayed, but if the current page text is clicked then a page number can be entered. A callback gets the current page number when it’s changed:

$('.pagination').jqPagination({
  paged: function(page) {
    // do something with the page variable
  }
});

In the callback, anything could happen: the current location could be changed, or an Ajax method could load more content from a RESTful API. The author has included CSS as part of the plugin’s source.

JavaScript Patterns, jQ.Mobi, Third-Party JavaScript

16 Jan 2012 | By Alex Young | Comments | Tags third-party books patterns mobile

JavaScript Patterns

The JavaScript Pattern Collection (GitHub: shichuan / javascript-patterns) by Shi Chuan is a collection of JavaScript patterns and anti-patterns including jQuery, functions, object literals and constructors, and object-oriented design patterns.

The jQuery patterns and anti-patterns are pretty good reading for anyone who writes plugins. The reasons for anti-pattern status are usually cited with a link to a post that covers why the technique is considered poor form. For example: universal-selector.html and requery.html.

jQ.Mobi

jQ.Mobi (GitHub: appMobi / jQ.Mobi, License: MIT X11) from appMobi is a framework aimed at HTML5 mobile browsers. According to the documentation, jQ.Mobi, is the “query selector” library. I thought this was confusing because surely a web framework that targets WebKit only has to wrap a small amount of functionality around querySelectorAll? In reality, this library includes most of what jQuery does: $.map, $.each, $.fn, css and attribute getters and setters, event handling, and even Ajax methods. There’s also a user interface library, and plugin support.

Each part of the library is presented as a monolithic file, and it doesn’t look like they’re built from smaller files. If this was my library, I’d split each of these files up into modules, with a build process that can output monolithic and minimised files. I’d also consider using the Asynchronous Module Definition specification to structure the library. It’s also slightly difficult to find the source – the homepage has a button that prompts for an email address, with a greyed out link to “No thanks, just get the code”.

The jQ.Mobi site claims that this is a rewrite of jQuery that targets WebKit mobile browsers, but we’ve already seen this several years ago at this point with libraries like Zepto. And there are also mobile interface libraries that are compatible with both jQuery and Zepto, like jQTouch, so I question the wisdom of coupling a jQuery clone with an interface library.

Writing Third-Party JavaScript Tutorial

Writing Quality Third-Party JS by Rakesh Pai from {errorception} is a tutorial series about writing third-party JavaScript. If you’re looking to scripts that run on other sites, like Disqus or Google Analytics, then this is an interesting read that covers the basics.

Third-party JavaScript The Book by Ben Vinegar and Anton Kovalyov can also be bought as part of Manning’s Early Access Program for $35.99. It looks like it’ll be the most thorough coverage of this topic once it’s finished.

Screenshot App, twss.js, WebGL Tunnel Tutorial

13 Jan 2012 | By Alex Young | Comments | Tags node webgl graphics

Screenshot App

Screenshot App (License: MIT) by TJ Holowaychuk is an Express app that uses PhantomJS to generate screenshots of web pages. It’s a small web service with a simple API that’ll return a PNG when called with a URL:

curl -# http://localhost:3000/example.com > example.com.png

This is a nice little example of an Express app. Like TJ’s other public apps, this one is structured around a lightweight app.js file, and then the HTTP methods are split into files in routes/. TJ defines the Express app object as a global, which means it’s visible inside the routes modules. There’s a lot to learn here if you’re an eager Express developer.

twss.js

Earlier this week a reader sent in twss.js (npm: twss, License: MIT) by Daniel Rapp, a classifier for Node that determines if a string can be replied with “that’s what she said”. I actually took a look at how it works, and rather than being a simple joke module, the author has actually attempted to build a K-fold cross-validation classifier. What’s even more hilarious is the module currently has 457 GitHub watchers.

The module includes data, so it’ll classify things out of the box:

twss.is("You're not going fast enough!");   // true

If you’re interested in classifiers, there are a few for Node – we’ve featured brain (npm: brain, License: MIT) by Heather Arthur before.

WebGL Tunnel Tutorial

I recently mentioned a WebGL tunnel effect created by Jerome Etienne. He’s now published his tutorial that explains how the demo works, in Tunnel Effect for Your Demo. By “demo” the title is referring to demoscene demos.

Amazingly, the source for the effect is only 20 lines.

Programming Styles in the Node Community

12 Jan 2012 | By Alex Young | Comments | Tags node style language

Programming style is where opinion and reason collide, often leading to endless arguments with no clear winner. The real secret to style is to be consistent, and respect other people: if you’re working on a project by another author, then follow their style. Some companies and open source projects may have their own in-house style guide, but it’s generally fairly easy to pick up the style of a project after browsing the source for long enough.

Why do I bring this up? Well, the Node community has several dominant styles, each with their own advantages. If you’re starting your own Node projects then you might like to use the style of a well-known developer for guidance of inspiration.

TJ Holowaychuk

TJ Holowaychuk, author of Express, Jade, Stylus, and Mocha, has an extremely consistent style. TJ uses two spaces for indentation, semicolons to end lines, and formats commas at the start of a new line:

var connect = require('connect')
  , Router = require('./router')
  , methods = Router.methods.concat('del', 'all')
  , middleware = require('./middleware')
  , View = require('./view');

This practice is becoming more common in JavaScript, and the arguments for and against it vary. Isaac Z. Schlueter created a gist on the subject at gist.github.com/357981 which grew into a heated debate that currently has 64 comments (since April 2010). It’s worth noting that TJ also carries this over to his JSON formatting, and generally only uses one var statement at the top of each new scope.

One of TJ’s more subtle stylistic habits is to remove the space before the opening brace of a method:

exports.parseQuality = function(str){
  // ...
};

When writing a function, however, he’ll usually retain the space:

function quality(str) {
  var parts = str.split(/ *; */)
    , val = parts[0];

  var q = parts[1]
    ? parseFloat(parts[1].split(/ *= */)[1])
    : 1;

  return { value: val, quality: q };
}

Notice that the ternary operator is split across new lines as well, which can make longer expressions more readable.

TJ also uses double quotes sparingly as well. Most strings are written using single quotes.

TJ’s Luna project isn’t related to JavaScript, but during development he made an interesting point: he likes the “machine-like” look of JavaScript’s operators. Some languages provide and instead (or as well as) &&, but TJ prefers the way operators like && read:

Personally I’m not a fan of “wordy” operators, aka or and for || &&, etc, though again they can look ok within reason, but I find the “machine-like” look of operators provide a nice visual separation.

I think the “visual separation” comment is interesting, because I find semicolons in JavaScript also provide visual separation, although other people may find this noisy.

 Isaac Z. Schlueter

Isaac Z. Schlueter, author of npm (where would we be without it?) is outspoken about style and language “magic”. I enjoyed reading his post Experts, Idiots, and Taste, and JavaScript is Not Web Assembly is related to this. Isaac doesn’t like language “magic”. He’s pragmatic and keeps things simple. Let’s take a look at his coding style.

Like TJ, Isaac uses leading commas and two space indentation, and usually groups variables under one var. Functions are spaced out like this: function help (args, cb) {.

The biggest difference between TJ and Isaac is semicolons. Isaac doesn’t use them to end lines unless necessary:

function checkGit (folder, cb) {
  // if it's a git repo then don't touch it!
  fs.lstat(folder, function (er, s) {
    if (er || !s.isDirectory()) return cb()
    else checkGit_(folder, cb)
  })
}

Isaac has written a detailed explanation of this decision in An Open Letter to JavaScript Leaders Regarding Semicolons. He makes good points as to why semicolons can be left out, although admits that this style may only be slightly superior.

Ryan Dahl

Ryan Dahl, creator of Node, has a slightly different style yet again. Like TJ and Isaac, he uses two spaces for indentation. Conversely, he’ll use multiple var statements per-line:

var express = require('express');
var socketio = require('socket.io');
var bench = require('./bench');

This is from d3bench, a small benchmarking app. He writes functions and methods with a single space: io.sockets.on('connection', function(socket) {. He doesn’t line up colons in object literals:

var r = bench.run({
  url: "http://localhost:8000/buffer/12345",
  concurrency: 10,
  requests: 50000
});

Deeper Style Choices

Indentation, semicolons, and other formatting topics are one side to coding style. Another is the choice of language features. Both TJ and Isaac use exceptions sparingly. Isaac is outspoken about exceptions:

I have settled in the last few years on the sentiment that try/catch is a mistake, and an anti-pattern.

This is from try/catch/throw on the Node Google Group.

TJ sometimes organises code into folders, with an index.js file, so a group of modules can be loaded with one require. Router in Express is an example of this. This technique removes a barrier from splitting up code into multiple files. Both authors also make heavy use of other Node modules, rather than reinventing their own solutions to common problems. The npm package.json is a good example of this.

Conclusion

Before starting a new project, it’s worth researching the programming styles used in the community of your chosen language and framework. Encourage the rest of your team to be consistent, even if they’re freelancers or contractors who have their own styles. The best comment I’ve read on how important it is to respect a project’s style is by Isaac:

In your own house, you get to decide the styles and customs. But be aware that it might have an effect on who feels comfortable at your parties.

Yes, it’s all FUD, in reply to Actual drawbacks to omitting semi-colons?.

References:

Node Roundup: Buster.JS, Word, Persist

11 Jan 2012 | By Alex Young | Comments | Tags node modules strings testing databases ORM
You can send in your Node projects for review through our contact form or @dailyjs.

Buster.JS

A reader sent in Buster.JS (GitHub: busterjs, npm: buster, License: BSD) by Christian Johansen and August Lilleaas, which is a new test framework for Node and browsers. It’s made up of a large set of modules that support everything from CommonJS assertions to JsTestDriver. The entire suite of modules can be viewed in the Buster.JS module documentation.

Asynchronous testing is supported through a callback function, similar to other frameworks, and promises. Any object with a then method is considered a promise:

function someAsyncTestFunction() {
  var promise = {
    then: function (callback) {
      this.callbacks = this.callbacks || [];
      this.callbacks.push(callback);
    }
  };

  setTimeout(function () {
    buster.assert(true);
    var callbacks = promise.callbacks || [];

    for (var i = 0, l = callbacks.length; i < l; ++i) {
      callbacks[i]();
    }
  }, 100);

  return promise;
}

Buster.JS supports setup and teardown methods, which can be nested inside groups of tests. Setup and teardown methods can also be asynchronous.

Tests can be written with TDD or BDD syntax, and several reporters are included, including a XML (which should work with test automation tools).

Buster.JS overview includes highlights and examples for the major features of the framework.

Word

Word (License: MIT, npm: word) by Veselin Todorov is a string library. It has methods for stripping slashes, stripping quotes, random strings, auto HTML links, and a lot more. It plays nicely with Express, so if you want to use these as helper methods then just call app.helpers({ word: word });

Persist

Persist (npm: persist, License: MIT) by Joe Ferner and Jeff Kunkle is a new ORM framework that supports SQLite, MySQL, PostgreSQL, and Oracle. Models and their relationships are defined using a chainable API. This example is from the project’s documentation:

var persist = require('persist')
  , type = persist.type;

// define some model objects
var Phone = persist.define('Phone', {
  'number': type.STRING
});

var Person = persist.define('Person', {
  'name': type.STRING
}).hasMany(this.Phone);

persist.connect({
  driver: 'sqlite3',
  filename: 'test.db',
  trace: true
}, function(err, connection) {
  Person.using(connection).all(function(err, people) {
    // people contains all the people
  });
});

As you can see, the Phone and Person models are defined in a fashion reminiscent of popular Node ODMs like Mongoose. The hasMany method sets up a relationship between the two models, and this also supports a through option for more complex join models.

The connection.chain(chainables, callback) method is one of Persist’s interesting features: it can take an array of chainable queries in sequence. This solves a common Node control flow issue without having to use a control flow library (or lots of nested callbacks).

jQuery Roundup: TextExt, Tesselate, Promptumenu, Stellar.js, session.js

10 Jan 2012 | By Alex Young | Comments | Tags jquery plugins animation forms sessions menus
Note: You can send your plugins and articles in for review through our contact form or @dailyjs.

TextExt

TextExt (GitHub: alexgorbatchev / jquery-textext, License: MIT) by Alex Gorbatchev is a modular library for enhancing text inputs. It supports features seen before in similar plugins, like a “tag” style UI, auto-completion, and Ajax, but the difference here is the modular design.

The TextExt plugin itself ships with a set of plugins, like Ajax and Autocomplete, that provide the functionality similar plugins keep in their ‘core’ code:

$('textarea').textext({
    plugins: 'autocomplete',
    autocomplete: {
        dropdownPosition: 'above'
    }
});

Notice that the API design means the plugin only adds a single entry to jQuery’s namespace. All of these plugins are documented in the very thorough TextExt manual.

Nethnic Tesselate

Tesselate

Nethnic Tesselate (License: LGPL) is provides some extremely slick grid-based transition effects. Lots of effects are possible, but I like the one shown in Tesselate Demo 1.

Promptumenu

Promptumenu (GitHub: natrixnatrix89 / promptu-menu, License: MIT and GPL) by Janis Zarzeckis displays a grid of icons that can be swiped, like the iOS or Android home screens. The author’s examples include grids of various sizes and page indicators.

Usage is pretty simple. Given an unordered list with suitably juicy icons, run promptumenu:

$('ul').promptumenu({
  width: 500,
  height: 500,
  rows: 4,
  columns: 4,
  direction: 'horizontal',
  pages: true
});

Stellar.js

Stellar.js (GitHub: markdalgleish / stellar.js, License: MIT) by Mark Dalgleish adds a parallax scrolling effect to an element as it’s scrolled. Try dragging the scroll bar on http://markdalgleish.com/projects/stellar.js to see how this works. It’s almost like a 16-bit video game!

The basic usage is simply $.stellar(). Effect options can be supplied by using data attributes, like data-stellar-ratio and data-stellar-background-ratio.

session.js

This isn’t technically a jQuery plugin, but is a useful bit of client-side scripting nonetheless. session.js (License: MIT) by Iain Nash collects information about the current session, like the screen resolution, geographical location, referrers, cookies, and more. This example by the author shows it being used to conditionally display an alert if the visitor came from Facebook:

<script type='text/javascript'>
  window.session = {
  options: { gapi_location: true },
  start: function(session){ // can also use window.session global.
    if (session.first_session.visits > 1){
      alert('Hi again from ' + session.location.address.city);
    } else {
      if (session.current_session.referrer_info.host.contains('facebook')){
        alert('Hi there from '+ session.location.address.city +'. How about liking us on facebook?');
      } else if (session.current_session.search.engine){
        alert('Did you find what you were looking for from ' + session.current_session.search.engine + '?');
      }
    }
  }
}
</script>
<script type='text/javascript' src="http://codejoust.github.com/session.js/session-0.4.js"></script>

It sounds like something that could be used to collect interesting statistics on site visitors, but in the past I’ve used a similar library of my own creation to enhance bug reports. When people filled out a bug report about my web apps I collected their user agent string, screen size and type, and other information that helped me track down rendering issues. So this library could find a lot of uses with a bit of creativity.

Ender Roundup: Swig, Traversty, NWMatcher, Ender-Overlay, Dagron

You can send in your Ender-related projects for review through our contact form or @dailyjs. Be sure to also update the Ender package list page on the Ender wiki.

Swig for Ender

Swig for Ender (npm / Ender: ender-swig), by Nicolas Chambrier, is a wrapper and build script for Swig, by Paul Armstrong. Swig is a fast template engine inspired by Django.

When included in an Ender build you get a $.swig object and a $.render method that lets you render templates from <script> tags by ID.

<script type="text/html" id="tpl">
Hello, {{ name }}.
</script>

<script type="text/javascript">
$.render('tpl', {"name": "dude"}) // →  "Hello, dude."
</script>

Swig also includes support for template inheritance:

<script type="text/html" id="parent">
Hello, {% block name %}John Doe{% endblock %}.
</script>
<script type="text/html" id="child">
{% extends 'parent' %}
{% block name %}dude{% endblock %}
</script>

<script type="text/javascript">
$.render('child') // →  "Hello, dude."
</script>

Swig depends on Underscore.js, which will be automatically included in your Ender build.

Another popular templating library for Ender is Wings (npm / Ender: wings) by Andrew McCollum, based on Mustache.

Traversty

Traversty (npm / Ender: traversty), by Rod Vagg, is a simple DOM traversal utility heavily inspired by Prototype’s “DOM traversal toolkit”. You get up(), down(), next() and previous() with optional selector and index arguments, all in a multi-element environment (jQuery-like rather than Prototype’s single-element implementation).

In their simplest form, up(), down(), next() and previous() let you move around the DOM by single-element steps but can be used like an optionally indexed find() in all four directions:

$('#root > ul') // can match and operate on multiple elements
  .down(0).css('color', 'red')
  .next('li', 1).css('color', 'green')
  .next().down('li', 2).css('color', 'blue')
  .next().down().css('color', 'yellow')
  .up(2).next().css('color', 'purple');

Traversty has no dependencies but will detect the presence of a selector engine if included in the Ender build (officially supports Qwery, Sel Sizzle and NWMatcher). Without a selector engine, Traversty will rely on native querySelectorAll() and the various vendor-prefixed native matchesSelector() implementations (available everywhere post-IE8).

Traversty can also be used as a stand-alone library:

traversty('li:nth-child(20)').previous('.interesting');

NWMatcher

NWMatcher (npm / Ender: nwmatcher), by Diego Perini is a battle-hardened selector engine with a strong focus on standards compatibility. It’s consistently fast across browsers and has continuing support for some very old browsers. NWMatcher became a popular alternative selector engine for Prototype users when the selector engine code was modularised in version 1.7. It continues to have a strong following, particularly amongst purists who appreciate NWMatcher’s close adherence to W3C standards.

NWMatcher now has Ender support and is in npm so can be easily included in your Ender builds: ender build nwmatcher undersore bonzo bean

Some of NWMatcher’s advanced features are supported directly via Ender:

// adjust NWMatcher's internals
$.configure({ USE_QSAPI: false, VERBOSITY: false });

// a collection containing the first match only, works like
// querySelector() and halts processing upon first match
$.first('div');

// just like calling $('div', root) but will trigger a callback
// function on each match found
$.select('div', root, callback);

// does at least one element in the current collection match
// the given selector?
$('div').match('.someclass');

// alias for .match()
$('div').is('.someclass');

// a new collection of child elements matching the given selector
$('div').find('.someclass');

// a new collection that includes the original collection and
// additional elements matching the given selector
$('div').and('.someclass');

As with all Ender modules, the original library can be accessed via require('nwmatcher'), this gives you the same object as NW.Dom when running outside of Ender.

NWMatcher has no dependencies and can be used as a stand-alone library.

Ender-Overlay

Ender-Overlay (npm / Ender: ender-overlay), by Andras Nemeseri is a highly configurable module for building dialogs, galleries, lightboxes etc.

<a id="trigger-vimeo" class="thumbs"><img src="http://www.samholdren.com/vimeo-Logo2.png" alt="Vimeo HTML5 Embed" width="100" height="100"></a>

<div id="overlay-vimeo" class="ender-overlay overlay-vimeo">
  <a class="close close-button" title="Close">&#9747;</a>
  <iframe src="http://player.vimeo.com/video/12132621?title=0&byline=0&portrait=0" width="601" height="338" frameborder="0" webkitAllowFullScreen allowFullScreen></iframe>
</div>

<script type="text/javascript">
$(document).ready(function() {
  $("#overlay-vimeo").overlay({ trigger: "#trigger-vimeo" });
});
</script>

Ender-Overlay

Andras has put together a tutorial, demos and documentation covering all options, events and methods on the Ender-Overlay page.

Ender-Overlay depends on the Jeesh (Ender’s official starter pack) and Morpheus for animation.

Dagron

Dagron (npm / Ender: dagron), by Dustin Diaz, is a very simple interface to HTML5 drag and droppables.

$('div.draggables').dagron({
    // all options are 'optional'
    handle: 'div.handle'
  , target: 'div.droptarget'
  , start: function(el) {} // el is the item you started dragging
  , drag: function(el) {} // el is dragged element
  , drop: function(el) {} // el is the target the dragged item was dropped on
  , enter: function(el) {} // el is the element target you entered into
  , leave: function(el) {} // el is the item left from
  , end: function(el) {} // el is the element you stopped dragging
})

Dagron depends on Qwery and Bean (both part of the Jeesh).

Tidbits

There were a couple of notable updates to Ender modules recently:

Bean

Bean, by Jacob Thornton, is Ender’s default event handling library. It received a major internal overhaul and a version bump to 0.4.x. Bean has a new internal registry for storing event handler data and it no longer relies on storing an ID on your DOM elements or your JavaScript objects. There have been some small fixes and optimisations and the inclusion of a new event.stop() method that invokes both event.preventDefault() and event.stopPropagation(), but otherwise the external API remains largely untouched.

Reqwest gets jQuery compatibility

Reqwest, by Dustin Diaz, is Ender’s native Ajax library, giving you a jQuery-like $.ajax() method. There are some differences in options between Reqwest and jQuery / Zepto which has caused some pain for jQuery users migrating to Ender and for libraries designed for jQuery integration, such as Backbone.js. In particular, jQuery uses type where Reqwest uses method, jQuery uses dataType where Reqwest uses type. Thankfully, Reqwest now has a compat mode. Calling $.ajax.compat() gives you access to the same option names as jQuery.

You can also install jQuery / Zepto mode as default in your projects with: $.ajax.compat && $.ender({ ajax: $.ajax.compat });

Full details can be found in the Reqwest README.

Sel gets CSS4

Sel, by Andrew McCollum, a selector engine for Ender, is one of the first selector engines to receive some CSS4 love. Working from the latest working draft, Andrew has enabled some excellent additions to Sel’s query syntax:

/* subject overriding, was '$div .box' in a previous CSS4 draft,
   returns 'div' rather than '.box' */ 
div! .box

/* id references, 'input' who's ID matches 'label's 'for' attribute */
label /for/ input

/* case insensitive attribute matching */
[attr = "val" i]

/* :nth-match and :nth-last-match to match against sub-selectors */
div:nth-match(3 of .box)

/* links who's target absolute URI matches the current document's URI,
   arguments specify the degree of locality */
a:local-link(0)

/* :column */
td:column(col.profit)

/* :nth-column and :nth-last-column */
td:nth-column(even)

The subject identifier (!) in CSS4 is going to be particularly useful for JavaScripters.

FeatherGL, TunnelGL, Gitview

06 Jan 2012 | By Alex Young | Comments | Tags git webgl

FeatherGL

FeatherGL (GitHub: bnason / FeatherGL, License: MIT) by Brandon Nason is a new lightweight WebGL library. It includes support for camera manipulation, lights, meshes, textures, scenes, and even shaders. There’s an online example of an animated teapot with FeatherGL which covers some of the basic features.

Like many other WebGL libraries, the API is based around namespaced objects:

var view = new Feather.View(new Feather.WebGL(canvas[0]));

// Create the Vertex Array
var vertices = 
    [
        [0, 0, 0], 
        [1, 0, 0],
        [-Math.cos(Math.PI*2/3), Math.sin(Math.PI*2/3), 0],
    ];
// Create the Vertex Index Array
var vertexIndexArray = [ 0, 1, 2 ];

// Create the Normals Array
var normals =
    [
        [0, 0, -1],
        [0, 0, -1],
        [0, 0, -1],
    ];

// Construct an RGBA color
var colors =
    [
        [1.0, 0.0, 0.0, 1.0],
        [0.0, 1.0, 0.0, 1.0],
        [0.0, 0.0, 1.0, 1.0],
    ];
var triangle = new Feather.Mesh(vertices, vertexIndexArray, normals, colors, Feather.MESH_TRIANGLE_STRIP);

TunnelGL

TunnelGL

TunnelGL (GitHub: jeromeetienne / tunnelgl) by Jerome Etienne is a small WebGL demo that looks like a demoscene tunnel effect straight out of the 90s. I suspect it’s going to form a tutorial on the author’s blog, Learning Three.js, but I’m including it here purely because I love tunnel effects.

Actually, it’s a good example of a project that uses Boilerplate for three.js, another one of Jerome’s projects.

Gitview

A reader sent in Gitview (GitHub: bouchon / Gitview, License: WTFPL) by Paul Bouchon is a widget that displays GitHub repository information. It can be used as a jQuery plugin, but is also framework agnostic:

var view = new Gitview({ 
  user    : 'bouchon',      // any github username
  domNode : document.body,  // domNode to attach to
  count   : 2,              // (optional) number of repos per widget page
  width   : '450px',        // (optional) width of widget
  compact : false,          // (optional) compact mode or full mode?
  noFrame : false,          // (optional) no fancy widget frame, just repositories
});

All that’s required to use Gitview on a page is the addition of the Gitview.js, which the author has hosted at http://logicalcognition.com/Projects/Gitview/Gitview.js.

Supporting AMD and Script Tags

05 Jan 2012 | By Alex Young | Comments | Tags frameworks tutorials lmaf amd

Let's Make a Framework is an ongoing series about building a JavaScript framework from the ground up.

These articles are tagged with lmaf. The project we're creating is called Turing. Documentation is available at turingjs.com.

Last week I started retrofitting Turing with AMD (Asynchronous Module Definition) support. This week I’ll complete most of this conversion to AMD by demonstrating how to use AMD modules both with and without a script loader.

Backwards Compatibility

James Burke, creator of RequireJS, contributed to Dojo’s script loader. As we’ve seen previously in this series, Dojo ships with a resource loader that’s capable of loading AMD modules, and is in fact built upon AMD. In contrast, jQuery conditionally supports AMD if a define function exists.

I wanted to do something slightly different: use define to express module dependencies, but still allow people to include Turing modules on a page without using a script loader. All modules are dependent on turing.core, and some are dependent on the dom and events modules. Turing contains some useful Underscore-like functionality in the turing.enumerable module, and I’ve always avoided reusing it in other modules because there wasn’t a way of expressing the dependency.

Therefore, I want Turing to be structured using AMD and to support these use cases:

  • Load modules with script tags
  • Use a monolithic, optionally minimised, build of the entire framework
  • Load Turing modules with a script loader

This means we need an alternative method to jQuery’s conditional AMD support. Dojo’s built-in script loader is another solution, but it’s actually a huge amount of work and people might not always want to use a script loader.

So, what do we do? There are a few ways to approach this problem:

  1. Make the build process change calls to define to work without a script loader
  2. Force people to use a script loader
  3. Patch define when not available

The first option seems like it would require too much maintenance – people would have to choose an AMD Turing download or a non-AMD version. The second option allows us to build Turing using AMD’s nice, modular structure, but completely breaks backwards compatibility. The third option has potential, and this is the one I spent some time exploring.

Patching define

To support AMD’s define method when an AMD-compatible script loader isn’t available, I added a method to turing.core:

// turing.core.js
(function(global) {
  var turing = {}, modules = {};

  // `turing.core`'s code goes here

  turing.define = function(module, dependencies, fn) {
    if (typeof define === 'function' && define.amd) {
      define(module, dependencies, fn);
    } else {
      if (dependencies && dependencies.length) {
        for (var i = 0; i < dependencies.length; i++) {
          dependencies[i] = modules[dependencies[i]];
        }
      }
      modules[module] = fn.apply(this, dependencies || []);
    }
  };

  // Export `define``
  if (typeof define === 'undefined') {
    global.define = turing.define;
  }
}(typeof window === 'undefined' ? this : window));

// turing.dom.js
define('turing.dom', ['turing.core'], function(turing) {
  // `turing.dom` source
});

By wrapping each module in a define statement, individual modules can now be loaded using RequireJS, and they’ll automatically load turing.core:

require(['turing.anim'], function(anim) {
  turing('#results').html('Turing has loaded with the DOM module.');
  turing.anim.chain(turing('#animate')[0]).move(1000, { x: '100px', y: '100px', easing: 'ease-in-out' });
});

The turing function here is the global turing method that will get exported to window. The turing.anim module has turing.core as a dependency, so we get the familiar turing function as expected.

This snippet is used by a functional test that I wrote to ensure Turing modules can be loaded with RequireJS. It’s a small Express app that can be found in test/functional/require.js.

Conclusion

jQuery is currently a monolithic framework (although the build process can be customised to remove unwanted libraries) which makes supporting AMD relatively easy. Conversely, Dojo is highly modular – it’s built on AMD and includes its own module loader.

Here I’ve presented an alternative solution that uses a lightweight version of AMD’s define method to support module loading through script tags, monolithic files, and AMD-compatible script loaders. It’s a potentially useful pattern for structuring large libraries and frameworks that have interdependent modules.

The code for this tutorial can be found in commit 4361042.

Node Roundup: i18next, Sift.js, Comb

04 Jan 2012 | By Alex Young | Comments | Tags node modules translation
You can send in your Node projects for review through our contact form or @dailyjs.

i18next

i18next (GitHub: jamuhl / i18next-node, License: MIT, npm: i18next) by Jan Mühlemann is a library for supporting multiple languages in Node applications. I previously posted about i18next in the jQuery Roundup.

i18next supports the expected set of translation tools, like pluralized strings, variables, and nesting. This Node port adds much-welcomed features like Express middleware and template support.

To add the required helpers to an Express app, call i18next.registerAppHelper(app), then use a familiar t() function to access translations in templates. The author provides a Jade example, so fans of the authentic TJ Holowaychuk Express/Jade/Stylus stack should be happy.

Sift.js

sift.js (npm: sift) by Craig Condon is a MongoDB-inspired array filtering library. It’s a bit like an alternative to Underscore for people who love MongoDB. Sift.js supports operators like $in and $gt, but can also filter arrays based on functions and even works with deeply-nested objects in arrays.

Craig has provided a few examples that should look familiar to Mongo users:

var sift = require('sift');

sift({ $in: ['hello','world'] }, ['hello','sifted','array!']);
// ['hello']

Full documentation is included, covering all of the supported operators and deep searching.

Comb

Comb (License: MIT, npm: comb) by Doug Martin is a framework for Node that includes “frequently needed utilities”, like logging tools, string and date formatting, flow control, and various collection algorithm implementations such as BinaryTree and PriorityQueue.

Every class provided by Comb has documentation at pollenware.github.com/comb. One of the interesting things I noticed about this project is the author claims 99% test coverage, so that fellow who filled out our JavaScript survey with “I code everything perfect on the first try” might want to check out the source.

jQuery Roundup: CraftMap, Scrollorama, Plugins Archive

03 Jan 2012 | By Alex Young | Comments | Tags jquery plugins geo maps animation
Note: You can send your plugins and articles in for review through our contact form or @dailyjs.

CraftMap

CraftMap

CraftMap (License: free for non-commercial use, Price: $49, Size: 13KB, Minified: 6.5KB) by Marcin Dziewulski is a lightweight plugin that turns an image into a map, complete with overlays and markers.

The plugin comes with lots of options, including saving position to cookies, map positioning, and controls.

Marcin has also written a whole slew of other plugins:

Scrollorama

Scrollorama

Scrollorama (GitHub: johnpolacek / scrollorama, License: MIT and GPL, Size: 9.63KB) by John Polacek is a plugin for controlling animations as a page is scrolled. Once a page is split into blocks, events can be triggered as blocks become visible:

var scrollorama = $.scrollorama({
  blocks: '.scrollblock'
});

scrollorama.onBlockChange(function() {
  alert('You just scrolled to block#' + scrollorama.blockIndex);
});

Elements can be animated, like the examples on Scrollorama’s site:

scrollorama.animate('#example1', {
  duration: 400, property: 'opacity'
});

Plugins Archive

After the official jQuery plugin site was shelved, the old content has now been reinstated at archive.plugins.jquery.com.

The new site is open source and can be found at GitHub: jquery / plugins.jquery.com. It can be installed locally, and requires a web server, PHP, MySQL, WordPress, Node, and Git.

Gerbil, Smoking, URI.js

02 Jan 2012 | By Alex Young | Comments | Tags libraries testing node browser

Gerbil

Gerbil (npm: gerbil) by Bruno Aguirre is a test framework for both Node and client-side development. Tests are structured in a BDD-like style, and assertions are included. It’s a small library but it offers a quick way to get started writing tests without many dependencies. I noticed that tests asynchronous code is supported because tests are run against a timeout, but there doesn’t appear to be an explicit “this test is finished” method call to directly support asynchronous code.

Tests with Gerbil look like this:

scenario('This is a group of tests', {
  'should assert true': function(g) {
    g.assert(true);
  }
});

Smoking

Smoking (npm: smoking), also by the same author, is a mocking and stubbing library. Prototype classes can be stubbed, and then expectations can be defined:

smoking(anObject).expects('aMethod');
smoking(anObject).verify();

When verify fails an exception will be raised, so this should be handled by most testing libraries.

URI.js

URI.js (GitHub: medialize / URI.js, License: MIT and GPL v3) by Rodney Rehm is a library for manipulating URIs that has a method chaining API. It makes manipulating everything from authentication details to query strings extremely easy:

URI('http://dailyjs.com/example.html')
  .directory('files')
  .hash('header')
  .query('field', 'value')
    // http://dailyjs.com/files/example.html?field=value#header

For a complete list of methods, see the URI.js API documentation.

Meincraft, Virtual Joystick, Filer.js

30 Dec 2011 | By Alex Young | Comments | Tags html5 filesystem libraries webgl

Meincraft

Meincraft screenshot

Meincraft (GitHub: mitsuhiko / webgl-meincraft, License: BSD) by Armin Ronacher a WebGL demo that generates terrain and allows navigation with its own camera implementation.

It’s currently a simple personal project rather than a fully-fledged web-based Minecraft engine, similar to the three.js Minecraft demo, but it’s an interesting start and different to the other WebGL Minecraft clones that I’ve found so far.

Virtual Joystick

Let’s Make a 3D Game: Virtual Joystick by Jerome Etienne is a tutorial on his virtualjoystick.js project which provides a joystick suitable for use with touchscreens. It works a lot like the joysticks seen in many iOS and Android games.

The tutorial post includes a demo, and it even works with a mouse. The basic API is simply var joystick = new VirtualJoystick().

Filer.js

Filer.js (GitHub: ebidel / filer.js, License: Apache 2.0) by Eric Bidelman is a friendly API for the HTML5 FileSystem API based around Unix commands. Most commands are asynchronous and expect a callback:

var filer = new Filer();
filer.init({size: 1024 * 1024}, onInit.bind(filer), onError);

function onInit(fs) {
  filer.ls('/', function(entries) {
    // entries is an Array of file/directories in the root folder.
  }, onError);
}

function onError(e) { ... }

That example lists a directory. Other familiar commands include cd, create, mkdir, rm, cp, mv, open, and write. Each API method is documented in the project’s README file in the repository.

Retrofitting AMD

29 Dec 2011 | By Alex Young | Comments | Tags frameworks tutorials lmaf amd

Let's Make a Framework is an ongoing series about building a JavaScript framework from the ground up.

These articles are tagged with lmaf. The project we're creating is called Turing. Documentation is available at turingjs.com.

Last week I looked at how AMD (Asynchronous Module Definition) works and how projects use it. This week I’m going to show how to retrofit it to an existing project, in this case our Turing framework, and hopefully you’ll be able to apply this to your own reusable client-side JavaScript.

Redefining Modules

Turing’s modules were structured around Immediately-Invoked Function Expressions (IIFEs), with CommonJS module loading support. AMD supports CommonJS modules, and Node can work with AMD too.

The core Turing module can be defined as an AMD module like this:

define('turing.core', [], function() {
  var turing = function() {};

  // Core functionality added here

  return turing;
});

A module loader is now needed to use this code in a browser. RequireJS works like this:

require(['turing.core'], function(turing) {
});

The methods in turing.core.js will be available once RequireJS has loaded the script.

Dependencies

A good reason for using AMD is dependencies can be specified and resolved by loaders. In Turing, every module depends on turing.core. That means the DOM module would have to be updated to look like this:

define('turing.dom', ['turing.core'], function(turing) {
  var dom = {};
  // DOM module defined here
  return dom;
});

Previously, expressing dependencies between modules wasn’t possible outside of code comments. Dependencies make it easier to break down functionality into smaller reusable chunks and loaded when required.

 Loading the Entire Framework at Once

When using frameworks like jQuery, many projects need a broad selection of functionality and therefore load the entire library rather than parts of it. Rather than forcing users to use require or define invocations with a large amount of dependencies, it’s possible to offer a broad selection in one file.

I’ve created a turing.js file that contains the following:

define('turing', ['turing.core', 'turing.dom', 'turing.anim'], function(core, dom, anim) {
  core.dom = dom;
  core.anim = anim;
  return core;
});

These are the modules that I’ve ported to work with AMD so far, but I’ll add all of them under turing.js once I’ve finished.

Building

What about building a monolithic, minified version of Turing? RequireJS addresses this by including the RequireJS Optimizer. This basically boils down to:

> npm install requirejs
> r.js -o app.build.js

Conclusion

I’ve started adapting Turing to work with AMD, and my early tests work with RequireJS. However, I’m finding it difficult to get builds to generate with r.js (it seems like the current release has bugs).

Although using AMD’s well-defined module pattern and dependencies solves certain problems when developing reusable code, it makes it difficult to satisfy users who simply want to include a library using a script tag without a module loader like RequireJS. I’ve been experimenting with creating a small define function that is used when a module loader isn’t available, and I’ll cover that in next week’s tutorial.