Why does JavaScript have default exports?

点点圈 提交于 2020-08-10 23:46:40

问题


Context

JavaScript has two types of exports: normal[1] and default.

EDIT: JavaScript has two types of export syntaxes

Normal exports

class Foo {...}
class Bar {...}

export {
  Foo,
  Bar,
};

or

export class Foo {...}
export class Bar {...}

Normal exports can be imported in two ways: namespace[1] imports and named imports (looks similar to destructuring).

Namespace imports

import * as Baz from './baz';

Named imports

import {Foo, Bar} from './baz';

Default exports

class Foo {...}
class Bar {...}

export default {
  Foo,
  Bar,
};

Default exports can also be imported in two ways: namespace imports and named imports (in a hackish way using destructuring in a separate statement)

Namespace imports

import Baz from './baz';

Named imports

import temp_Baz from './baz';
const {Foo, Bar} = temp_Baz;

Question

Both normal exports and default exports have the same functionality - they can be imported into a namespace, and they can be destructured into smaller pieces.

1) What are the reasons JavaScript has default exports, instead of sticking with just normal exports and having the import syntax be the following?

import <varName> from <location>;

<varName> would allow destructuring like any variable assignment, without a special "named" import.

Node.js managed without default exports, and the only additional change would be to allow exporting of a single value:

module.exports = class Foo {...}

This could be done with export = or export only or something similar:

export only class Foo {...}

So now you might ask, what is the difference between export only and export default?

  • export only exports could be imported with the same syntax, whereas export default requires a different importing syntax. To allow both syntaxes to work for the module user, the module must both export and export default the same items (which is something I do in all my modules).
  • export default is renamed to export only which is a better term in my opinion (less confusing; clearer)

2) All the differences listed above are pros. Are there any other differences that are cons? Or can any of the above differences also be cons?


Edit

It seems I misunderstood the intended use for export default.

It's for adding a default export on top of the regular exports.

So I'd now like to know when are default exports used? Although I probably shouldn't add more to this question.

If the only use for default exports is if your module only has a single item to export, then this question still applies.

Edit 2

Now it seems that the intended use is if a module only exports a single item. So my question still applies. Why not replace default exports with export only, removing the need for an additional default import syntax?


Notes

[1] I am not sure if this is the correct term to use


回答1:


JavaScript has two types of exports: normal and default.

No, not really. JavaScript has only one kind of export structure. It has different syntaxes though.

export default function x() {} is just a shorthand notation for function x(){} export { x as default }.
import x from '…' is just a shorthand notation for import { default as x } from '…'.

The difference between your the two module exports you discussed is much bigger than the single default keyword. They only look so similar because you used shorthand notations. Fully spelled out, it's

export {
  Foo as Foo,
  Bar as Bar,
} // a declaration

vs

export default ({
  Foo: Foo,
  Bar: Bar,
}); // an object literal

Both normal exports and default exports have the same functionality - they can be imported into a namespace, and they can be destructured into smaller pieces.

No, they don't. Imports provide aliases for the exported variable declarations, there's no destructuring - and you cannot do that to properties of a default-exported object.

What are the reasons JavaScript has default exports, instead of sticking with just normal exports and having the import syntax be the following?

See https://esdiscuss.org/topic/moduleimport. The default-export syntax provides a shorthand syntax for exporting under the special name default (which is not a valid variable name otherwise), as it is a quite common use case to export only a single thing from a module. It doesn't require explicitly naming a value when there is only one in this module anyway. In this regard, it has very much the purpose you envisioned for your export only suggestion, but it is only one export not providing a full namespace of multiple aliasable exports.




回答2:


export default {
  Foo,
  Bar,
}

I don't understand why you've demonstrated this structure. This isn't how it's supposed to be used.

The default export really be though of as just another export. If you import * as Package from "package" you'll realise... Package.default is the default export

The only change is the syntactic shortcut:

import alias from "package" = import {default as alias} from "package"

It makes consumption of many packages easier / simpler.


export = ... is not the same as export default ...

The prior returns a module structure of ... where as latter returns a module structure of {default: ...}



来源:https://stackoverflow.com/questions/57020740/why-does-javascript-have-default-exports

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!