The Dojo Foundation was founded for the purpose of facilitating an active and open community of web technology, making high-quality code accessible to developers without constraint. The Dojo community has a history of commitment to the open web, with active involvement in many standards bodies and interoperability efforts, dedication to standards based approaches with the move to the AMD format and promises implementation, HTML5-based store API, data attributes, to-the-letter HTTP REST implementation, and more. The Dojo Foundation is working to further advance the open web with the introduction of a JavaScript package repository.
Backdraft Framework, the leading candidate for the future Dojo module loader
other AMD-compatible module loaders
Flexibility, Performance, and Stack Traces
This refactoring gives Dojo excellent flexibility going forward, to support both legacy synchronous loading mechanisms, as well as new asynchronous script-tag based loading that provides significant performance boosts and debugging improvement (including real stack traces!).
The CommonJS AMD proposal defines an elegant, simple API for declaring modules that can be used with synchronous or asynchronous script-tag based loading in the browser. RequireJS already implements this API, and Dojo will soon have full support as well. The API for defining modules is as simple as:
define(, , );
This simple API can be used in a variety of different ways for different situations.
Data querying is a critical component of most applications. With the advance of rich client-driven Ajax applications and document oriented databases, new querying techniques are needed, and Resource Query Language (RQL) defines a very simple but extensible query language specifically designed to work within URIs and query for collections of resources. The NoSQL movement is opening the way for a more modular approach to databases, and separating out modeling, validation, and querying concerns from storage concerns, but we need new querying approaches to match more modern architectural design.
For developers that are creating libraries and modules, it is generally preferable to make your code available to as broad of range of users as possible. There are several different module formats in JavaScript (a module is an encapsulation of code that draws on other modules). Picking one format is often mutually exclusive to the other formats. However, in this post I want to demonstrate how you can write JavaScript modules that can be used with multiple module loaders using some simple boilerplate. Of course not all the module loaders necessarily make sense for all modules. If you are writing a module that relies on the Node file system API, it only needs it to work with the NodeJS/CommonJS module format. Likewise, a DOM-based module wouldn’t need to run on Node.
Here we’ll deal with the actual module format, the mechanism of specifying dependencies and exporting or returning functions from the module that can be used by the users. This does not deal with the normalization of the actual APIs of the underlying system, although you might want to take a look at promised-io if you would like normalization of IO interaction across the browser, Node, and Rhino/Narwhal.
Patr (Promise-based Asynchronous Test Runner) is a simple lightweight cross-platform test runner for promised-based applications. Patr executes tests by simply executing functions of an object and is intended to be used in combination with the “assert” module (which is available on NodeJS and Narwhal), so tests can be as simple as:
Promises are a well-established mechanism for modeling future or asynchronous actions. Promises allow asynchronicity while maintaining the core programming principles of composability and encapsulation. Writing asynchronous code in JavaScript can often be a confusing exercise due to the extensive need for callbacks, but promises help to define composable units of asynchronicity to encapsulate actions and reliably separate caller and callee’s concerns.
Promised-IO
Promised-IO utilizes promises as an abstraction for I/O operations on top of Node, Narwhal/Rhino, and the browser (where possible). This serves two purposes. First, this package provides the benefits of promise usage: clean separation of concerns and proper encapsulation of eventual values. Second, Promised-IO provides a consistent normalized interface for I/O that will work on multiple platforms without sacrificing any of the advantages of asynchronous I/O, making it easy to build modules that can be used by developers on many platforms.
Nodules is a module loader for Node that provides a powerful set of features for application development and distribution. Nodules was written to solve the two major missing pieces of functionality I needed for efficient application development: flexible dependency resolution and module reloading. Nodules runs on top of Node’s simple base module loader, and nicely compliments the base loader with additional functionality. Furthermore, it provides this functionality using idiomatic asynchronous techniques, a smart package layout, and powerful module reloading.
Node is a server-side JavaScript platform that is known for being well suited for Comet-style applications that utilize long-lived connections to allow applications to send messages from the server to the browser asynchronously. In fact, the beginning of the front page of nodejs.org starts out with an example of a web application that delays for a couple seconds before sending a response without any type of blocking; the code is asynchronous and efficient.
However, building a real-life real-time application involves more than just a platform that gives you asynchronous communication, there are a number of other important techniques to understand. We will look at these techniques and introduce project Tunguska that provides some helpful tools to assist in building applications. While a number of Comet projects out there attempt to provide a black box solution to Comet, Tunguska recognizes that most real-time applications involve deep integration into the application and its security, messaging, and data structures. Consequently Tunguska is a set of tools for building real-time applications rather than a closed black box that can’t easily be integrated with. Let’s look at some of these tools.
Modules are an integral architectural piece of robust application development since they allow individual components to be developed with proper dependency management. Modules can specify dependencies and these can be automatically resolved and loaded to bring various pieces together automatically. In application development this is vastly more scalable and easier than having to track all the different dependencies and manually load modules or insert script tags.
The CommonJS module format is increasingly ubiquitous as the de facto module format for JavaScript. However, if CommonJS modules, by themselves, are directly executed, they require synchronous loading of modules. Synchronous loading is known to be very problematic in the browser since it locks the browser user interface, requires eval-based compilation of scripts which confuses debuggers, and is less efficient than using standard script tags.