ES5 Module Systems (was: Alternative proposal to privateName.public)

James Burke jrburke at gmail.com
Mon Dec 26 21:48:21 PST 2011


On Mon, Dec 26, 2011 at 1:46 PM, Mark S. Miller <erights at google.com> wrote:
> On Mon, Dec 26, 2011 at 12:15 PM, Axel Rauschmayer <axel at rauschma.de> wrote:
>> The adapters are all a bit cumbersome to use. IMHO, the best option is
>> still boilerplate (to conditionally turn an AMD into a Node.js module):
>>
>>     ({ define: typeof define === "function"
>>         ? define
>>         : function(A,F) { module.exports = F.apply(null, A.map(require)) }
>> }).
>>     define([ "./module1", "./module2" ],
>>         function (module1, module2) {
>>             return ...
>>         }
>>     );

This type of boilerplate may not be processed properly by AMD
optimizers that insert module IDs into the define call when multiple
modules are combined together. While the above may work with the
requirejs optimizer, it is not guaranteed to work in the future. I
still prefer the define() call is a non-property function call and not
a call to an object method, to avoid possible conflicts with a module
export value (uglifyjs has one such conflict). A bit more background
in this message:

http://groups.google.com/group/nodejs-dev/msg/aaaf40dfeca04314

In that message I also mention encouraging the use of the "amdefine"
adapter module in Node. Use of this module will help test drive a
define() implementation that could be integrated into Node later, and
by having Node packages use the module, it would give Node committers
a way to scan the package.json info to find out if define() use is
used enough to warrant consideration in their core.

"amdefine" also supports a callback-style require (with callback fired
on nextTick()) and most of the loader plugin API, so it gives an idea
how big a complete define() implementation in Node might be:

https://github.com/jrburke/amdefine

But if inline boilerplate is desired instead of a dependency on an
npm-installed module, there are a set of options in this project:

https://github.com/umdjs/umd

which include boilerplates that also work in a "just use globals with
ordered HTML script elements" browser setup. I personally prefer this
one if AMD+Node support is desired:

https://github.com/umdjs/umd/blob/master/returnExports.js

I also encourage any ES.next module system to allow opt-in to an
ES.next module system using a similar type of boilerplate. However, I
am concerned that the declarative nature and new syntax needed for
ES.next modules would make this difficult to do. I have given feedback
offline to Dave Herman about it and was not going to bring it up more
publicly until later, but given the talk of boilerplate, seems
appropriate to mention it here.

James


More information about the es-discuss mailing list