ModuleImport

Chris Toshok toshok at gmail.com
Thu Jun 19 11:29:35 PDT 2014


On Thu, Jun 19, 2014 at 11:06 AM, Erik Arvidsson <erik.arvidsson at gmail.com>
wrote:

> On Thu, Jun 19, 2014 at 1:23 PM, Chris Toshok <toshok at gmail.com> wrote:
>
>> On Thu, Jun 19, 2014 at 6:57 AM, Erik Arvidsson <erik.arvidsson at gmail.com
>> > wrote:
>>
>>>
>>> On Thu, Jun 19, 2014 at 6:41 AM, Calvin Metcalf <
>>> calvin.metcalf at gmail.com> wrote:
>>>
>>>> One other option could be for import name from 'path'  to resolve to
>>>> the module body there is no default export, thanks to the static analysis
>>>> you'll always know when default is present.
>>>>
>>> That is a refactoring hazard. If the module changes to add/remove the
>>> default export the import will still succeed but the value is either a
>>> module instance object or anything:
>>>
>>>  // a.js
>>> export default class C { ... }
>>>
>>> // importer.js
>>> import A from './a';
>>> new A();
>>>
>>> Now a.js changes.
>>>
>>> // a.js V2
>>> export class C { ... }
>>>
>>> // importer.js
>>> import A from './a';
>>> new A();  // TypeError: A is not a function
>>>
>>> With this idea you cannot look at the import statement to see if the
>>> imported binding is a module instance object or not.
>>>
>>>
>> I think you're example misses one point - The module author changed the
>> exported api, going from exporting a function named C to exporting an
>> object with a property named C.  Problems caused by this refactoring would
>> exist regardless of Calvin's suggestion.
>>
>
> With the current spec this is a compile time error since a.js (V2) does
> not export default.
>

Correct, but:

```js
// a.js
export default class C { ... }

// a.js V2
export default { C: class C { ... } }
```

The author changed the shape of the api here as well, preserving default
export.  Hazards abound once you have an importer.  That's what I meant by
problems caused by that sort of refactoring existing regardless of Calvin's
suggestion - if the shape changes there's nothing you can do in the general
case.

By adopting something like Calvin's suggestion we can remove a possible
module-side hazard, caused by the fact that the shape of an api
artificially differs between default export and named exports.


>
>>
>> Calvin's suggestion would allow the following refactoring to be done by
>> the module author without impacting his users, something not possible with
>> current ES6:
>>
>> ```js
>>  // a.js V1
>> export default { C: class C { ... } }
>>
>
> But this is the thing we are trying hard to have people never do.
>

What exactly is it we're trying to have people do?  never export more than
1 thing?  or never export an object literal, instead favoring
Object.create(null, { })?

-chris


>
>>
>> // a.js V2
>> export class C { ... }
>> ```
>>
>> The refactoring hazard is real, but exists iff the module consumer uses
>> implicit exports (i.e. an Object.prototype method with the above default
>> export).  This is another reason why the named export form is better -
>> everything is explicit.  IMO the only good reason to use default export is
>> to export a single function.
>>
>> -chris
>>
>>
>
>
> --
> erik
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20140619/b95fe065/attachment.html>


More information about the es-discuss mailing list