> From: John Barton [mailto:[email protected]]
> 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. 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.

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`.  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.

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.

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.
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to