Coder Perfect

For ES6 import, when should I use curly braces?

Problem

Although it appears to be self-evident, I was perplexed as to when to apply curly brackets when importing a single module in ES6. For example, I have the following file and its content in the React-Native project I’m working on:

var initialState = {
    todo: {
        todos: [
            {id: 1, task: 'Finish Coding', completed: false},
            {id: 2, task: 'Do Laundry', completed: false},
            {id: 2, task: 'Shopping Groceries', completed: false},
        ]
    }
};

export default initialState;

I need to import it without curly brackets in TodoReducer.js:

import initialState from './todoInitialState';

If I put curly brackets around initialState, I get the following error for the following line of code:

export default function todos(state = initialState.todo, action) {
    // ...
}

Similar issues also occur with my curly braces components. I was wondering when I should use curly braces for a single import, because I know you have to encapsulate multiple components/modules in curly braces when importing multiple components/modules.

Instead of asking when I should or should not use curly braces for importing a single module in ES6, I’m asking when I should or should not use curly braces for importing a single module in ES6 (this is apparently not the case, as I have seen single import with curly braces required).

Asked by TonyGW

Solution #1

This is a standard import:

// B.js
import A from './A'

It only works if A’s default export is set to:

// A.js
export default 42

It doesn’t matter what name you give it when importing it in this case:

// B.js
import A from './A'
import MyA from './A'
import Something from './A'

Because whatever A’s default export is, it will always resolve to that.

A: is the name of the named import.

import { A } from './A'

It will only function if A has a named export named A:.

export const A = 42

In this case the name matters because you’re importing a specific thing by its export name:

// B.js
import { A } from './A'
import { myA } from './A' // Doesn't work!
import { Something } from './A' // Doesn't work!

To make them work, you’ll need to add a named export to A:

// A.js
export const A = 42
export const myA = 43
export const Something = 44

There can only be one default export per module, but you can have as many named exports as you like (zero, one, two, or many). You can import them all at the same time:

// B.js
import A, { myA, Something } from './A'

We import the default export as A, as well as specified exports named myA and Something.

// A.js
export default 42
export const myA = 43
export const Something = 44

When importing, we may also give them all distinct names:

// B.js
import X, { myA as myX, Something as XSomething } from './A'

The default exports are often used for whatever you’d expect from the module. The named exports are typically used for utilities that are useful but not necessarily required. However, you have complete control over how things are exported: a module, for example, may have no default export at all.

This is an excellent introduction to ES modules, including an explanation of the differences between default and specified exports.

Answered by Dan Abramov

Solution #2

There’s also a starred notation for the import ES6 keyword that’s worth highlighting, in my opinion.

If you try to console log, you’ll get the following error:

import * as Mix from "./A";
console.log(Mix);

You will get:

When you just need select components from a module, brackets come in handy, resulting in smaller footprints for bundlers like webpack.

Answered by prosti

Solution #3

The default exports and named exports are explained in Dan Abramov’s response.

Which to use?

David Herman, to quote him: The single/default export style is preferred by ECMAScript 6, and importing the default has the best syntax. Importing named exports can, and should, be a little less succinct.

However, because of refactoring, named export is preferred in TypeScript. For example, if you rename a default exported class, the name will only change in that file and not in other references; whereas, with named exports, the name will be altered in all references. For utilities, named exports are also preferable.

In general, do whatever you want.

Additional

Because default export is a named export with the name default, it may be imported as:

import {default as Sample} from '../Sample.js';

Answered by Deepak Sharma

Solution #4

Import is very intuitive if you think of it as syntax sugar for Node.js modules, objects, and destructuring.

// bar.js
module = {};

module.exports = {
  functionA: () => {},
  functionB: ()=> {}
};

 // Really all that is is this:
 var module = {
   exports: {
      functionA, functionB
   }
  };

// Then, over in foo.js

// The whole exported object:
var fump = require('./bar.js'); //= { functionA, functionB }
// Or
import fump from './bar' // The same thing - object functionA and functionB properties


// Just one property of the object
var fump = require('./bar.js').functionA;

// Same as this, right?
var fump = { functionA, functionB }.functionA;

// And if we use ES6 destructuring:
var { functionA } =  { functionA, functionB };
// We get same result

// So, in import syntax:
import { functionA } from './bar';

Answered by Brandon

Solution #5

Exports:

There are two kinds of exports:

Syntax:

// Module A
export const importantData_1 = 1;
export const importantData_2 = 2;
export default function foo () {}

Imports:

The way something is imported is affected by the type of export (i.e., named or default exports):

Syntax:

// Module B, imports from module A which is located in the same directory

import { importantData_1 , importantData_2  } from './A';  // For our named imports

// Syntax single named import:
// import { importantData_1 }

// For our default export (foo), the name choice is arbitrary
import ourFunction from './A';

Things of interest:

Aliases can be used to rename a named import whenever you wish. The following is the syntax for this:

import { importantData_1 as myData } from './A';

We’ve now imported importantData 1, but instead of importantData 1, the identification is myData.

Answered by Willem van der Veen

Post is based on https://stackoverflow.com/questions/36795819/when-should-i-use-curly-braces-for-es6-import