David Herman dherman at
Thu Jun 19 01:15:48 PDT 2014

Thanks to everyone for working through the issues around ModuleImport. I know it's been frustrating, but the discussions have really helped clarify the key constraints.

## Constraints

First, let me restate the most important arguments. In favor of removal:

* **The syntactic distinction between ModuleImport and default import is vague.**

We've consistently seen confusion between the semantics of ModuleImport and default export. While certainly some of the confusion might be chalked up to misinformation and lack of documentation, we've seen people be confused by this even when correctly explained the semantics. The problem with the syntax is that the only visual distinction is the initial keyword (`module` vs `import`), and it's not clear from that keyword which concept you're talking about. (Once you've internalized the structure of module instance objects, you get a hint from the `module` keyword, but that doesn't help people who are just learning the system, particularly if they're already familiar with other JS module systems.)

Against removal:

* **Without ModuleImport, authors of multi-export modules would be pressured to circumvent the named exports functionality.**

Without ModuleImport, clients of multi-export modules have two options. Either they use named import:
import { readFile, writeFile } from "fs";
or if they want to explicitly namespace those functions, they have to use the dynamic API:
import "fs"; // state the dependency
var fs = this.get("fs");
That's inconvenient, confusing, and makes you feel like you're stepping outside the normal usage patterns intended for the system. Since this is a choice forced on the clients of a module, the module author will feel pressure to circumvent the named export feature altogether and instead export a default object with all the properties. This is bad -- it creates pressure for people to abandon part of the module system.

## Conclusion

Here's the conclusion I've come to based on all of the above.

* **We need a form like ModuleImport.**

As many have said, clients of named-export modules need the freedom to choose whether to explicitly namespace those imports, and they need a syntax that doesn't feel like they've stepped outside the normal system.

* **The current syntax of ModuleImport is wrong.**

The confusion reported in developer feedback is real, and it's important.

* **The syntax should still favor default import.**

ES6 favors the single/default export style, and gives the sweetest syntax to importing the default. Importing named exports can and even should be slightly less concise.

* **A better ModuleImport syntax is possible, and we should settle it soon.**

I'll propose a better ModuleImport syntax below. Syntax being syntax, everyone will of course unsheathe their bikeshed paintbrush. That's OK. The champions will keep it from going on unbounded and help settle the debate, and we'll make sure to capture the conclusion in the next TC39 meeting.

I do acknowledge the concerns about reopening topics for debate and delay. But given the usability feedback, I think this case is worth fixing. We should resolve it for ES6, perhaps in part because it's less editorial work to change the ModuleImport production than to defer it, but more because I don't want to delay the resolution so that implementations can ship the better syntax. But keep in mind it doesn't matter what spec it lands in as long as implementations are shipping it. We're still in the early days of transpiler implementations, and there are no native implementations of modules yet. So there's time, as long as we don't let the bikeshed go on forever. So let's get to it!

## Proposal

OK, so we're talking about a better syntax for importing a module and binding its named exports to a variable (as distinct from importing a module and binding its default export to a variable). Here's my proposal:
import * as fs from "fs"; // importing the named exports as an object
import Dict from "dict";  // importing a default export, same as ever

Why is this better? Because it dovetails with the named export syntax, **which makes it clear that it's binding `fs` to the named exports.** It saves the reader from having to know that the module instance object is not the same thing as the default export.

So there you have it... Feedback welcome, and as always we'll collect it all, weigh it, and try to shepherd consensus.

Oh, and just to put parameters on the discussion:

* **I'm not proposing additional new import forms.**

If this syntax is future-compatible with other possible syntactic forms, that's great, but that's not what we're discussing.

* **I'm not interested in discussing changes to the rest of the module syntax.**

This isn't the time or place to redesign the whole system.

* **The `this` binding in modules is a separate topic.**

The `this` binding in modules can be discussed independently of this topic.

tl;dr we're only talking about the ModuleImport syntax here.


More information about the es-discuss mailing list