ES Modules: suggestions for improvement

Sam Tobin-Hochstadt samth at
Wed Jun 27 11:56:28 PDT 2012

On Tue, Jun 26, 2012 at 2:54 PM, Isaac Schlueter <i at> wrote:
> The linked blog post is a very rough cut of where my thoughts are on
> the subject.  Expect changes and cleanup.  It does not represent a
> fully-baked (or even half-baked) idea, but more like a general
> direction.

Your post makes four criticisms of the module system design.  The
first two are about the runtime module loaders API, and the second two
are about the language extensions for writing modules in source code.

> It seems to be based on the assumption that nesting module systems is a thing that
> people want.

> It puts too many things in JavaScript (as either API or syntax) which belong in the
> host (browser/node.js).

These first two misunderstand what the module loaders API provides.
In particular, you *don't* have to write a module system to use it.
We agree that almost everyone just wants the defaults to work, and
we've tried to design for that.  Here's a really simple example:

    System.load("", function(mod) { return
mod.do_stuff(); } )

Here's another example, constructing and installing a module at runtime:

    System.set("add_blaster", { go : function(n,m) { return n + m; } })

Then we can use the module like this:

    System.load("add_blaster", function(ab) { return ab.go(4,5); })

or, since we know that "add_blaster" is a local module:

    let { go } = System.get("add_blaster");

or, if we put the call to `System.set` in the previous script tag, we
can just do:

    import go from "add_blaster";

At no point here did we have to write a module system.

Of course, the loader API is designed to give programmers more
flexibility than this. If you want to create a sandbox, or set up
modules to be cached in localStorage, or rerouted through a CDN, then
you can make that happen.  But you don't have to use these facilities
to get your work done.

> It borrows syntax from Python that many Python users do not even recommend
> using.

Certainly, `import *` makes it easier to get name clashes, and we've
designed the system to be resistant to a lot of them.  However, it's
great for getting things done quickly, which I hope we all want to
keep supporting.  Maybed IDEs for JS will eventually support the same
features that they do for Java, to unfold the * into a bunch of
specific imports, but for hacking something together, convenience and
not repeating lots of names is a big win.

> It favors the “object bag of exported members” approach, rather than the “single
> user-defined export” approach.

Here I just disagree.  I think supporting this:

module m {
    export function f() { ... }
    export function g() { ... }

is important.  Otherwise, you have to repeat yourself, like so:

module m {
    function f() { ... }
    function g() { ... }
    export {f : f, g : g }

Of course, the latter is supported too, so if you want to do all your
exports in one place, that's fine.  However, I have not seen any
discussion of why the "single export" approach is superior -- just
saying that "it is widely acknowledged" isn't very persuasive,
especially given the troubles with cycles.  In contrast, the more
declarative approach makes handling cycles straightforward.

sam th
samth at

More information about the es-discuss mailing list