This chapter provides an overview of Dojo's architecture, takes you through installing Dojo, introduces some domain-specific jargon, runs through the bootstrapping process, and then provides some example code that should whet your appetite for the chapters that follow. Like any other introduction, much of this chapter paints in broad strokes and sets the tone for the rest of the book. Hopefully, you'll find it helpful as you begin your journey with the toolkit.
As you're about to see, describing Dojo as a toolkit is no mere coincidence. In addition to providing a JavaScript standard library of sorts, Dojo also packs a collection of feature-rich, turnkey widgets that require little to no JavaScript coding at all, build tools, a testing framework, and more. This section provides an overview of Dojo's architecture from a broad point of view, shown in Figure 1-1. As you'll see, the organization for the rest of this book is largely driven by the toolkit's architecture. Even though DojoX is displayed as an independent entity from Dijit, DojoX resources could also be built upon Dijit resources, just as your own custom widgets could leverage any combination of Dijit and DojoX resources.
Figure 1-1. One depiction of how the various Dojo components can be thought of as relating to one another
The kernel of Dojo is Base, an
ultra-compact, highly optimized library that provides the foundation
for everything else in the toolkit. Among other things, Base
provides convenient language and AJAX utilities, a packaging system
that allows you to pull in Dojo resources on-the-fly instead of
requiring them to all be slurped in when the page loads. It also
supplies you with tools for creating and manipulating inheritance
hierarchies, a means of almost universally querying the DOM using
CSS3 selectors, and a fabric that standardizes DOM events amongst
various browsers. Everything that Base provides is available in the
top level of the toolkit's namespace as a dojo.*
function or attribute. Base comes
packaged as a single file, dojo.js, which comes
across the wire at under 30KB, and when you consider that most
Flash-based advertisements that inundate the web are considerably
larger than 30KB, such a small number seems quite amazing.
Tip
If you look at the actual size of dojo.js on disk, you'll see that it is around 80KB, but because web servers generally process content as it comes "across the wire" to the browser, it's the size of the compressed content that drives the amount of time it takes to download. If you manually apply gzip compression to dojo.js, you should see that it reduces in size by about one-third of the original size.
One other really interesting thing about Base is that it is
designed to bootstrap the Dojo essentials
automatically by simply including the dojo.js
file into the page. To oversimplify things a bit, bootstrapping
basically entails detecting the environment, smoothing out browser
incompatibilities, and loading the dojo
namespace. Various configuration
options can also be specified to automatically parse any widgets in
the page and perform other initialization tasks. (All coming up in
future chapters.)
Base provides a tremendous wealth of utility for many standard operations you'll commonly need to achieve when doing just about anything in JavaScript. Even if you don't use anything else in the toolkit, Base will probably be a valuable resource that you won't want to live without once you've experienced the productivity boost it provides. There is no Dojo without Base; everything in the toolkit depends or builds on it one way or another.
Tip
With the contents of the Base being settled and fairly uniform, the terms "Base" is being used less and less within the project as time goes on, and you may even hear the term "Base" used interchangeably with "dojo.js."
Core builds on Base by offering additional facilities for
parsing widgets, advanced animation effects, drag-and-drop
facilities, internationalization (i18n), back-button handling,
managing cookies, and more. Resources available through Core are
often used frequently and provide fundamental support for common
operations, but were not deemed universal enough to include in Base.
Although the distinction between what did and didn't make it into
Core may not be a perfect boundary, Dojo's packaging system
trivializes the amount of effort required to pull in additional
modules and resources as needed with a simple mechanism that works
like a #include
from C or an
import
statement from
Java.
In general, distinguishing between Base and Core is simple:
any module or resource that you have to explicitly import into the
page external to dojo.js is a part of Core if
it is associated with the dojo
namespace. Core facilities usually do not appear in the Base level
namespace, and instead appear in a lower-level namespace such as
dojo.fx
or dojo.data
.
Describing Dojo as just a JavaScript standard library of sorts would only be telling you a small part of its story; Dojo also packs a fantastic library of widgets called Dijit (short for "Dojo widget") that is ready to use out of the box and often doesn't require you to write any JavaScript at all. Dijits conform to commonly accepted accessibility standards such as ARIA[7] and come with preconfigured internationalization that spans many common locales. Dijit is built directly upon Core (providing a strong testament to Core's integrity), so whenever you need a custom widget of your own devising, you'll be using the very same building blocks that were used to create everything else in Dijit. The widgets that you create with Dojo are ultra-portable and can easily be shared or deployed onto any web server or often even run locally without a web server at all via the file:// protocol.
Plugging a dijit into a page is as easy as specifying a
special dojoType
tag inside of an
ordinary HTML tag—a dream come true for layout designers and users
who aren't interested in doing a lot (or any) JavaScript
programming. In fact, a key benefit of using Dijit for application
developers is that it allows you to achieve incredibly rich
functionality without having to dig into tedious implementation
details. Even if you're more of a library-writing type or a custom
widget developer, following Dijit's style and conventions ensures
that your widgets will be portable and easy to use—essentials for
any reusable software component.
The Dijit battery can be roughly divided into general-purpose application widgets like progress bars and modal dialogs, layout widgets like tab containers and accordion panes, and form widgets that provide super-enhanced versions of old hats like buttons and various input elements.
DojoX is a collection of subprojects that officially stands for "Dojo Extensions," although it is often called "Extensions and Experimental." The "extensions" subprojects in DojoX accounts for stable widgets and resources that while extremely valuable just don't fit nicely into Core or Dijit; the "experimental" subprojects account for widgets that are highly volatile and in more of an incubation stage.
Each DojoX subproject is required to come with a README file that contains a synopsis of its status. Although DojoX subprojects strive to meet accessibility and internationalization initiatives consistent with Dijit, it is not generally the case that they're always quite that refined. Be that as it may, lots of heavy machinery for real world applications lives in DojoX, including the grid widget, data converters for common web services, etc. DojoX also provides a sandbox and incubator for fresh ideas, while simultaneously ensuring that the high standards and stable APIs for resources in Core and Dijit are not compromised. In that regard, DojoX strikes a sensitive balance for critical issues central to any community-supported OSS project.
Util is a collection of Dojo utilities that includes a JavaScript unit-testing framework and build tools for creating custom versions of Dojo for production settings. The unit-testing framework, DOH,[8] does not have a specific coupling to Dojo and provides a simple set of constructs that can be used to automate quality assurance on any JavaScript code. After all, you do want to implement well-defined, systematic tests for your JavaScript code, don't you?
The essence of the build tools is that they shrink the size of your code and can aggregate into a set of layers, where each layer is nothing more than a collection of other JavaScript files. The compression is accomplished via ShrinkSafe, a patched version of Mozilla's powerful Rhino JavaScript engine that compresses JavaScript code without mangling public APIs, and the aggregation is accomplished with a collection of custom scripts that are also run by Rhino. Other auxiliary components in Util do things like inline HTML template strings (more on this when Dijit is formally introduced in Chapter 11) into JavaScript files—another trick for reducing latency.
Tip
While reading this section, you may understand what build tools do for you, but it may not be clear why you'd want them. In short, build tools that consolidate and minify your JavaScript code significantly reduce the HTTP latency, which yields a serious performance advantage when it comes time for production.
Like DOH, ShrinkSafe may be used independently of Dojo, and for production settings there is almost never a good reason not to use it, given that it is not uncommon for it to reduce the JavaScript footprint by 50% or more. The performance difference between loading many large JavaScript files via a series of synchronous requests and retrieving one or two compressed JavaScript files can be quite staggering.
[7] A standard for accomplishing Accessible Rich Internet Applications: http://www.w3.org/WAI/intro/aria.
[8] As you might already have been thinking, DOH is also a pun on Homer Simpson's famous expletive; the test runner can optionally play a "D'oh!" sound effect when a test fails.
Get Dojo: The Definitive Guide now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.