http://wiki.ecmascript.org/doku.php?id=conventions:commonjs_adaptor
This builds on work by Peter Michaux, Isaac Schlueter, and myself to
demonstrate that CommonJS modules can be written to seamlessly migrate
from existing <script> systems (where the scripts are manually ordered
from least to most dependent topologically) to managed module systems.
Mark's implementation adds a stub require for scripts that uses the
global object as a module memo. In a browser, scripts are
self-naming, but in a CommonJS system, they are anonymous. So this is
similar to a transport format. I believe both approaches are useful.
Mark points out in the notes that modules conforming to the CommonJS
module conventions should be fine in SES, a secure subset of
ECMAScript.
Kris Kowal
(function(require, exports) {
"use strict";
// ...
exports.x = 21;
}).apply({}, typeof require === 'function' ? [require, exports] :
[function(g){return function(id){return g[id];};}(this._modules = this._modules || {}),
this._modules['example/foo'] = {}]);
I'm not really a fan of distributing your modules with any kind of boilerplate, but since it's compatible with normal CommonJS loaders it's certainly better than RequireJS's approach of including the transport boilerplate in your original modules.
> --
> You received this message because you are subscribed to the Google Groups "CommonJS" group.
> To post to this group, send email to comm...@googlegroups.com.
> To unsubscribe from this group, send email to commonjs+u...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/commonjs?hl=en.
>
Dealing with nested dependencies and sequencing of the evaluation of
modules in the correct execution order are the harder bits to work out
for browser loading. This recommendation is another take on a function
wrapper for modules, but it is hard to see how it adds more to making
it easier to consume CommonJS modules in the browser, particularly
when some of the other transport formats give more information on a
module's dependencies outside the execution of the module.
In what cases would this type of wrapper be more useful? It seems
unlikely that a site that already ordered its dependencies correctly
via plain script tags would move to this syntax given the the
verbosity of it. They would create a helper function wrapper for it,
and once that happens, it seems to fall more in line with the other
transport proposals. They may save some some size on the
implementation of their wrapper/loader, since it could not do
dependency resolution/ordering, but that is saving at most 4 KB of
minified/gzipped content. A site with enough script tags to make this
worthwhile will not notice the difference in performance of losing
4KB, and still lose out significantly on the benefits of a loader that
can trace dependencies and load via async script tags that will give
better performance vs inlined script tags.
James
--
Thanks,
Kris
It is the keyword based format that makes it impossible to create a
compatible library for ES3/5 that is concerning, but I suppose that is a
discussion for es-discuss someday...
--
Thanks,
Kris
~Daniel Friesen (Dantman, Nadir-Seen-Fire) [http://daniel.friesen.name]
Per spec,
(function () {
"use strict";
// global object is no longer on the scope chain
// and no longer provided as "this" by default
})();
Implementations are catching up.
Kris Kowal
On Mon, Sep 13, 2010 at 9:46 AM, Wes Garland <w...@page.ca> wrote:Per spec,
> Figure out how to make an ES5 scope that can't read from the global object,
> then we'll talk.
(function () {
"use strict";
// global object is no longer on the scope chain
// and no longer provided as "this" by default
})();
Implementations are catching up.
Kris Kowal
--
You received this message because you are subscribed to the Google Groups "CommonJS" group.
To post to this group, send email to comm...@googlegroups.com.
To unsubscribe from this group, send email to commonjs+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/commonjs?hl=en.
On Mon, Sep 13, 2010 at 10:17 AM, Kris Kowal <kris....@cixar.com> wrote:On Mon, Sep 13, 2010 at 9:46 AM, Wes Garland <w...@page.ca> wrote:Per spec,
> Figure out how to make an ES5 scope that can't read from the global object,
> then we'll talk.
(function () {
"use strict";
// global object is no longer on the scope chain
// and no longer provided as "this" by default
})();That's incorrect. Free variables within the function body are still references to global variables. (A DeclarativeEnvironmentRecord wrapping) The global object is still at the bottom of the scope chain.
Nevertheless, this insulation is possible in ES5 without needing to write a full lexer or parser in JavaScript: <https://mail.mozilla.org/pipermail/es-discuss/2010-August/011684.html>
Implementations are catching up.
Kris Kowal
--
You received this message because you are subscribed to the Google Groups "CommonJS" group.
To post to this group, send email to comm...@googlegroups.com.
To unsubscribe from this group, send email to commonjs+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/commonjs?hl=en.
--
Cheers,
--MarkM
Mark, won't this approach break in the presence of cycles, though?
// foo.js
exports.bar = require("bar")
// bar.js
var foo = require("foo")
assert(foo.bar === exports)
It seems like the boilerplate could be modified to support the "not
yet done" approach that we've been using in the various ssjs
platforms:
[function(g){return function(id){return g['/'+id] = g['/'+id] || {};};}(this),
this['/example/foo'] = this['/example/foo'] || {}]);
Of course, that means that when a module can't be found, it won't
throw, so I'm not sure how one would work around that. Of course,
whichever tool is generating this code would know ahead of time which
modules it's going to define, and could handle that case easily
enough.
--i