ModuleImport

John Barton johnjbarton at google.com
Fri Jun 20 16:51:37 PDT 2014


On Fri, Jun 20, 2014 at 4:17 PM, Ron Buckton <rbuckton at chronicles.org>
wrote:

> > From: John Barton [mailto:johnjbarton at google.com]
> > Sent: Friday, June 20, 2014 3:48 PM
> >
> > ES6 already has what you want:
> >
> > _Named Exports_:
> >
> > export var foo = 1;
> >
> > _Single Export Object_:
> >
> > export var moduleName = {
> >   foo: 1,
> >   bar: function() {}
> > };
> >
> > _Single Export Function_:
> >
> > export function fName() { }
> >
> >
> > And even cooler, the syntax for import is uniform,
> >
> > import {foo} from './namedExport';
> >
> > import {moduleName} from './singleExportObject';
> >
> > import {fName} from './singleExportFunction';
> >
>
> I'm not stating that I specifically "want" anything here, but was rather
> recommending an alternative approach to the single export vs named export
> debate and the removal of the ModuleImport production.


Sorry, I did understand that. I was (cryptically) recommending that
removing ModuleImport and `export default` until a later date gives us a
good-enough solution to the cases you outline. These features can be added
at a later very easily and since they would be based on real users asking
for more features we could move on them quickly.



> David's mail was proposing the addition of the following syntax:
>
> ```
> import * as fs from "fs"
> ```
>
> This is designed to work around the fact that without ModuleImport,
> there's no simple way to get the module object for the named exports. What
> you really want to write is:
>
> ```
> import fs from "fs";
> ```
>
> However, the current semantics don't allow this.  David proposed the new
> syntax as a replacement for ModuleImport. My only issue is that for the end
> user this could be confusing, and its possibly future-hostile for
> refactoring.
>

So let's just remove it and export default and go. No confusion. We make
progress. We study real feedback. We reconsider.


>
> If I have a library today that uses an object literal as a default export
> in Node, and I want to migrate to ES6, the easiest approach is to just
> replace `module.exports =` with `export default`.


Easing migration is a great goal for the next release.  We can refine
ModuleImport between now and then.


> My consumers would happy use `import foo from "foo"`. If I later want to
> move to named exports, I would break my consumers as they would have to
> change this to `import * as foo from "foo"`.  The whole reason for this is
> that there is a semantic distinction with how a default export is handled
> vs. how named exports are handled.
>

Exactly. So don't allow default export. Presto, problem solved.


>
> If I were to use TypeScript's syntax for exports and imports, changing
> from a default export to named exports results in no change for the
> consumer:
>
> [before.ts]
> ```
> export = {
>   foo: 1,
>   bar() {}
> }
> ```
>
> [after.ts]
> ```
> export var foo = 1;
> export function bar() {}
> ```
>
> [consumer.ts]
> ```
> import before = require("before");
> import after = require("after");
> before.foo; // 1
> before.bar; // function bar() {}
> after.foo // 1
> after.bar; // function bar() {}
> ```
>
> Albeit, TypeScript does not have a Module exotic object, nor does it have
> mutable bindings, nor an ImportList in its import clause. That said, as far
> as the consumer is concerned there's no real distinction between the
> "default export" approach in before.ts and the "named export" approach in
> after.ts.  We have this distinction in ES6 because it was designed that way
> to support mutable bindings and cyclic dependencies. I'm proposing that we
> come up with alternative semantics that preserve that approach while
> keeping the import syntax simple.
>

I think both export default/module import and cyclic dependency support are
marginal features that cause as many wacky problems as the solve. They just
don't matter one way or another.  The export default/module-import are easy
to add later: removing them now is simple. Changing the semantics means
redesigning modules.


> As a module consumer, I would constantly need to be aware of whether I
> need to use the `import * as foo from "foo"` syntax or the `import foo from
> "foo"` syntax. Where in Node I would use `require("foo")` for both cases.
> By changing the semantics of ImportDeclaration in ES6 and using a simpler
> syntax, we could would save developers the cognitive cost of determining
> which import syntax to among two very similar forms, as well as supporting
> the ability for a module author to refactor their module from a default
> export to named exports for the single-export-as-object case without
> affecting their consumers.
>

Omitting export default and module-import achieves the same cognitive
savings.

jjb
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20140620/7aab424b/attachment.html>


More information about the es-discuss mailing list