[dojo-contributors] Module formats for the browser

Kris Zyp kzyp at dojotoolkit.org
Mon Mar 29 09:12:50 EDT 2010

On 3/29/2010 2:05 AM, Rawld Gill wrote:
>> -----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. 

I think there is already consensus that we won't use this for Dojo's
modules. The CommonJS transport wrapper is LBF and basically already
works with RequireJS, so I presume you aren't say that we should somehow
try to ensure that all user modules are completely hand-coded and that
no one ever uses any bytes that originated from any automated tool. Not
sure how we would police that ;).

> 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).

Does this differ at all from James' approach and his multi-build setup?
Are you suggesting something different than him?

More information about the dojo-contributors mailing list