-1

I found a strange situation in ES6. For example, I'm using npm packages react and react-router. I want to import them to the file:

import React from "react";
import { browserHistory } from "react-router";

The strange situation is that I need to wrap browserHistory in figure brackets, but I don't need to wrap React. What is the reason?

import { React } from "react"; // React is undefined
import browserHistory from "react-router"; // browserHistory is undefined

What's the reason that I need to customize my import?

Alex Antonov
  • 14,134
  • 7
  • 65
  • 142
  • 1
    [MDN - export](https://developer.mozilla.org/en/docs/web/javascript/reference/statements/export) [MDN - import](https://developer.mozilla.org/en/docs/web/javascript/reference/statements/import) – zerkms Jun 07 '16 at 06:22
  • Wild guess: there is a default exports, which is used by React. So in browserHistory you are exporting that method and in react you are getting the default which has a different name, or getting the whole thing. – Francisco Presencia Jun 07 '16 at 06:24

2 Answers2

3

ES6 modules differentiate between two kinds of exports: default exports and other exports.

Every module can have at most one default export. A default export is kind of like the “main attraction” of a module. It’s supposed to be the one thing that you probably meant the module to have. All other exports fit into the other category.

So a module can have any number of exports (even zero), of which at most one can be a default export.

On the export side of the syntax, a default export is simply marked by adding a default after the export keyword:

// this is a normal export
export var foo = 'foo';

// this is a default export
var bar = 'bar';
export default bar;

On the import side of the syntax, this gets a it more complicated: Default exports are imported outside of curly braces. All other exports are imported inside curly braces.

import bar, { foo } from 'some-module';

This would import the default exported member of the module as bar and also import the (named) other export foo. Note that default exports do not have a fixed name: The original name of the member at export time does not matter. Instead, you give it some name when importing it. So you could also write this instead:

import baz, { foo } from 'some-module';

This would still import the same default export from the module, but give it a different name. Other imports however are required to have the correct name, since that’s what’s used to identify them. You can however give them a different name by using the as keyword.

There are a few more things to know when using the export and import statements. You should check MDN for a full description of them.

poke
  • 369,085
  • 72
  • 557
  • 602
  • 1
    `default` is special because it's a keyword, but at it's core, it's just a name for an export like any other name. You can't export two things with the same name, whether the name is `default` or something else. Also note `export default bar;` isn't the only way to export a default. You can also do `export {bar as default};`, which has the added benefit that you'll get live binding of `bar` too. – loganfsmyth Jun 07 '16 at 06:49
0

If the module you are importing has a default export, then you do not have to use the { } syntax to access the given export. Named (non-default) exports must be accessed via the { } syntax. A module can have a default export as well as many named exports.

An example of that would be React which is a default export, but the module also has a named export of Component. To import both of these exports the syntax: import React, { Component } from 'react' would be used.

httpNick
  • 2,524
  • 1
  • 22
  • 34
  • 1
    "If the module you are importing has a default export, then you do not need the { } syntax" --- this is vague. `import React, { Component } from 'react';` is a common statement. Irregardless of presence of the default export you may or may not need to use named imports. – zerkms Jun 07 '16 at 06:28
  • Thanks @zerkms I edited my answer to hopefully fix the issue my original answer had. Let me know or edit further if my point isn't getting across very well. – httpNick Jun 07 '16 at 06:32
  • "to access a property" --- it's not a "property", but a named export. – zerkms Jun 07 '16 at 06:32
  • `s/to access an export/to access named exports/` – zerkms Jun 07 '16 at 06:35
  • 1
    @poke You could always `import {default as React} from` instead of `import React from` if you wanted. – loganfsmyth Jun 07 '16 at 06:36
  • @httpNick Feels like it could still use some work. It's not whether the module has many exports, it's whether you are trying to import one of those or the default. – loganfsmyth Jun 07 '16 at 06:40
  • @loganfsmyth Interesting, didn’t actually know that was possible. Thanks! – poke Jun 07 '16 at 06:46