[dojo-contributors] Module formats for the browser

James Burke jburke at dojotoolkit.org
Thu Mar 25 19:53:38 EDT 2010


On 3/25/10 8:14 AM, Kris Zyp wrote:
> This CommonJS module standard format is what I am recommending that we
> use for Dojo source code.
>
> So why would we use the CommonJS module format if it necessitates server
> side wrapping? I know there is extra burden for server side wrapping,
> but I believe there are several key reasons this is advantageous:
> * All Dojo modules can be CommonJS compliant modules, and easily be
> reused on any CommonJS platform.
>    

But the dojo user's modules may not be CommonJS-compliant. It feels like 
we are setting up a "class" system where the user's modules are inferior 
or require extra work to reuse. I think one of the powers of Dojo's 
codebase is that we use the same tools, the same widget base classes as 
dojo users. Treating their code as "other" does not sit well with me. 
This also gets to my core beef with CommonJS modules:

[start rant]
I truly believe that CommonJS got the module format wrong. It was wrong 
to treat the browser as an afterthought, and the async capabilities 
recently only help a little bit, and they are still second class.

Functions as a module container fit with JavaScript. Returning a value 
from that function to define the module is also very JavaScripty. The 
exports thing to me is an eyesore, and it boggles my mind that setting 
the exported value was not allowed. Sure there is talk of it now, but 
the APIs for it seem goofy. If it started with a function wrapper, it 
would be a lot cleaner. I know there is a circular reference cost to 
return values, but that cost is very small and easy to work around. 
CommonJS will probably need a setExports at some point and so they will 
have taken that circular reference cost too. The CommonJS format is 
trying to optimize the wrong things.
[end rant]

> * There is less boilerplate that has to be written (and maintained) by
> us as developers than the load-by-function approach.
>    

I believe this is a premature optimization, trying to avoid a function 
wrapper style for modules. At least in the browser. As soon as you need 
to debug, any sort of advantage the non-wrapper solution might have had 
will be eaten up dealing with setting up some sort of sync system that 
can work in an async environment.

Plus, the module pattern in JS code (function(){}()); is very common. 
Given that it is in use, the extra stuff to define a module ends up not 
being that much different. Functions are the natural module system in 
JavaScript. Trying to avoid them feels like trying to avoid the braces 
in JavaScript: that is just how the language worked out. Get used to it.

> * Modules are decoupled from their namespace, making them much more
> portable.
>    

I can see that renamespacing is a weakness of including module IDs in 
the definition. But we have had that issue in Dojo for a very long time, 
and as I recall it is not onerous to correct. Measure the time needing 
to renamespace some code vs. setting up work for server transforms. I 
believe the work for renamespacing happens much fewer times, and can be 
helped via tools.

Don't get me wrong, I do see the need for module IDs in the format as a 
weakness, but in the grand scheme of things, if it means direct 
debugging and use in the browser, that tradeoff is worth it.
> Also, the server wrapping process is intentionally extremely simple and
> I think could easily be ported to all the platforms we play on. The
> module that is wrapped does not need to be internally modified at all. I
> included the code for a very simple wrapping below. I also have a small
> github project that demonstrates more advanced, full server side
> dependency resolution (packaging multiple modules in one response) for
> server side JavaScript servers [2].
>    

It is awesome that you have a server side process, and I know Dustin has 
worked on one before for existing Dojo code. They are definitely nice to 
have, and we should support them, but the support should be optional. We 
need something that works well with just files on disk because I believe 
some mobile platforms server their HTML/JS/CSS like that.

What I would rather see is that we develop our code via RequireJS, and 
we provide adapters that can convert CommonJS modules to RequireJS 
syntax (I have one now), and I really want to get RequireJS running on 
the server. It runs in Rhino now, I want to get a Node fork going at 
some point.

Although I can see that using RequireJS in the server may be 
unrealistic. If that is the case, then perhaps provide some sort of 
adapter that can convert RequireJS formatted modules to the CommonJS 
format. It might be hard given that RequireJS allows setting the export 
value, but maybe by the time we get there, the CommonJS module spec will 
have finally allowed setting export values.

This feedback is a bit strongly worded, and definitely not directed at 
you Kris. I admire the work you have done in the CommonJS group and 
trying to bridge the gaps. If the rest of the dojo contributors feel 
there is value in the CommonJS approach, I will understand and keep out 
of the way for that. I am a bit surprised and disconcerted with myself 
that I feel so strongly about this, but I do. I do not want to code in 
the CommonJS format. It is inferior. I may have to just suck it up 
someday and get used to it, but I am not ready to do that now.

James



More information about the dojo-contributors mailing list