[dojo-contributors] Module formats for the browser

Rawld Gill rcgill at earthlink.net
Mon Mar 29 04:05:39 EDT 2010


> -----Original Message-----
> From: dojo-contributors-bounces at mail.dojotoolkit.org [mailto:dojo-
> contributors-bounces at mail.dojotoolkit.org] On Behalf Of Kris Zyp
> Sent: Thursday, March 25, 2010 8:15 AM
 
> Reviving this old thread... There has been a lot of work lately in
CommonJS in
> improving asynchronous module loading, and I think it is now at the point
> were it makes sense for Dojo to align with CommonJS modules for future
> Dojo module loading. 

[snip]

Sorry for the late join; I've been away.

I am very happy to see continued support and discussion for moving to an
asynchronous loader, likely leveraging the requireJS API. I've been doing a
lot of work in this environment and it is really hard to accept the
synchronous loader after you make the switch.

Since commonJS/dojo are targeted for grossly different environments
(server/browser), they, by definition, have different requirements and
constraints. Dojo should never knowingly employ a less optimal design simply
to be compliant with another project unless publishing a mediocre solution
will delight many more customers than will notice the mediocrity. I highly
doubt this is the case with commonJS, but maybe I don't know.

The idea that dojo devs will code modules one way, and everybody else who
isn't that smart another way is a bad one. Certain classes of projects make
heavy use of the module system. To these devs, one of dojo's key selling
points is the module system. The more complex/less optimal that system is,
the more likely they are to choose something else. I understand that they
don't have to use the commonJS format, but if it is the dojo standard-even
for a module that would never be used server side-then others will follow.

I am strongly against "the CommonJS format with a server side module
wrapper":
* it requires preprocessing to use the module asynchronously
* it is not canonical JavaScript design (as James suggests)
* I don't agree that there's necessarily less boilerplate; at worst, it's
minimal.
* [as other's have mentioned] decoupling modules from their namespace is
laudable, ...and almost always provides little value. You could also just as
easily write a server-side process to decouple a LBF module from its
namespace, so this isn't really an advantage of the commonJS format.

I strongly favor the load-by-function module (LBF) pattern that is
exemplified by requireJS.

As James mentioned, I've been working on a version of dojo and dijit for the
last couple of months (as time permits) that uses the load-by-function
module pattern. To date, I have.
* converted all dojo and dijit modules to LBF
* made some minor mods to doh to clean up a few issues
* converted all dojo tests and have them all working
* created a new dojo.js that includes an asynchronous loader; the loader is
mostly API compatible with requireJS. 

At this point, I believe I can produce a version of dojo that can be loaded
by *either* the asynchronous loader *or* the current synchronous loader with
a couple of minor, backward compatible, mods. I haven't published this work
to the group because it is not done and I am still experimenting with a few
places where my ideas diverge from James's (and I haven't had time to
discuss these issues with James yet).

I believe the migration path should be to release a 1.x version of dojo that
can use either the current synchronous loader or a new asynchronous loader.
My current goal is to offer such a system as soon as 1.5 is released, based
on the 1.5 code. (The synchronous loader should be dropped in 2.0, and
perhaps a synchronous loader add-in provided.but these are issues for
another day.)

* Two, separate bootstraps should be included (say dojo and dojo-ng). The
user chooses the loader by choosing the bootstrap.
* All non-bootstrap module code should work with both loaders. This should
incur zero performance penalty and slightly decrease raw module size.
* All current tests should work as they do now assuming the 1.x loader is
selected.
* All currents tests will have some, mostly rote, reworking required to use
the asynchronous loader. I have already done this work for dojo. I have not
done this for dijit or dojox. I haven't given much thought to designing a
single test stack work with both loaders--TODO.
* The current build system will have to be modified to understand the LBF
module format when executing builds for the 1.x loader.

I've got a list of details for how to get from here to there, but they're
not ready for public consumption; here are the bullet points:

* Make the modifications to the current loader to handle LBF modules.
Roughly this implies:

dojo.def(
  "dojo/dnd/Manager", [
    "dojo", 
    "dojo/dnd/common", 
    "dojo/dnd/autoscroll", 
    "dojo/dnd/Avatar"], 
  function(dojo) {
    //.
  }
);

...causes...

dojo.provide("dojo.dnd.Manager");
dojo.require("dojo");
dojo.require("dojo.dnd.common");
dojo.require("dojo.dnd.autoscroll");
dojo.require("dojo.dnd.Avatar");
function(dojo) {
//.
}
to be executed.

* Convert all modules from using the dojo.provide/require pattern to use the
LBF module pattern.
* Make a few *backward compatible* modifications to the dojo code that are
needed for the LBF module pattern. The key areas I am aware of are loading
i18n modules (which have to be pulled to the LBF require vector for the
module) and dojo.declare (which needs the ability to accept a context into
which to stuff the new class when a class name is given).
* Write a new dojo.js (I called mine dojo-ng.js) that includes the LBF
loader and a couple of dojo functions that are significantly different in
the LBF environment (e.g., set/getObject).

Best,
Rawld




More information about the dojo-contributors mailing list