12

I am learning Javascript imports and I am yet to understand when we use curly braces while importing items(functions, objects, variables) from another JS file.

import Search from './models/Search';
import * as searchView from './views/searchView';
import { elements, renderLoader } from './views/base'
//elements is an object, renderLoader is a function
Bony
  • 151
  • 2
  • 8
  • 1
    depends on what is being exported - your own question has 2 versions that do not use `{}` - so, your question is not clear at all - [here's some helpful documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import) – Jaromanda X Aug 06 '18 at 05:30
  • @JaromandaX I assume they added those 2 versions to show that often import is being used without `{}`. – connexo Aug 06 '18 at 05:32
  • I understand the versions where {} are not used. But , I don't know why {} should be used in the last case. – Bony Aug 06 '18 at 05:33
  • 1
    it depends on how many `exports` does the source object have if one or default then no need to use the `{}` else if the source object has multiple then you can specify `{}` and just select the ones that you want to use. – vikscool Aug 06 '18 at 05:34
  • what's important is the export - import and export work hand in hand, without understanding the export, you won't understand the import – Jaromanda X Aug 06 '18 at 05:34
  • The symbols you import may or may not have an impact on the total bundled size of your application (when using a bundler). See [_"tree shaking"_](http://2ality.com/2015/12/webpack-tree-shaking.html). [In the past](https://github.com/webpack/webpack/issues/2713), `import *` made it difficult to isolate used and unused parts of code but these days, I believe it doesn't make a difference – Phil Aug 06 '18 at 05:42
  • 1
    Wow, so many answers of varying quality - almost none give the whole story - read the manual – Jaromanda X Aug 06 '18 at 05:44
  • I read all the answers and then read then the documentation at MDN. I understand it now, thanks. I am sorry I can't up-vote the answers, I don't have the privilege to up-vote yet. – Bony Aug 06 '18 at 05:53
  • 1
    @Bony you've got 15 rep, you should be able to [vote up](https://stackoverflow.com/help/privileges/vote-up) – Phil Aug 06 '18 at 05:55
  • The answer you have approved is not correct. Please re-check and verify. – UtkarshPramodGupta Aug 06 '18 at 06:44
  • @UtkarshPramodGupta Your comment about the approved answer being incorrect is no longer true. – connexo Aug 06 '18 at 18:46

8 Answers8

13

The import statements are used to import the exported bindings from another module

The curly braces ({}) are used to import named bindings and the concept behind it is called destructuring assignment The concept of destructuring assignment is a process that makes it possible to unpack the values from arrays or objects into distinct variables in the imported module

The curly braces ({}) are used to import named bindings

I would like to explain different types of imports in ES6 with the help of an example

Suppose we have a module named Animals(Animals.js) let suppose the module exports a default binding Man and several other named bindings such as Cat, Dog etc

/*
 Animals.js
*/
..
export Cat;
export Dog
export default Man

Import a single export from a module

In order to export a single export from another module (let's say Cat) we can write it like this

/*
 Anothermodule.js
*/
import {Cat} from "./Animals"

Similarly for Dog

/*
 YetAnothermodule.js
*/
import {Dog} from "./Animals"

Import multiple exports from module

You can also import multiple modules as follows

/*
 Anothermodule.js
*/
import {Dog, Cat} from "./Animals"

Import an export with a more convenient alias

/*
 Anothermodule.js
*/
import {Dog as Puppy}  from './Animals.js';

Rename multiple exports during import

/*
 Anothermodule.js
*/
import {Dog as Puppy, Cat as Kitty}  from './Animals.js';

But in the case to import Man into another module since it is a default export you can write it like this

/*
 Anothermodule.js
*/
import Man  from './Animals.js';

You can also mix both the above variants for example

/*
 Anothermodule.js
*/
import Man, {Dog as Puppy, Cat as Kitty} from '/Animals.js';

Import an entire module's contents

If you want to import everything you can use

/*
 Anothermodule.js
*/
import * as Animals from './Animals.js';

Here, accessing the exports means using the module name ("Animals" in this case) as a namespace. For example, if you want to use Cat in this case you can use it like below

Animals.Cat

You can read more information about import here

you can read about destructuring here

starriet
  • 2,565
  • 22
  • 23
SAMUEL
  • 8,098
  • 3
  • 42
  • 42
  • Great answer. Also, you can use an alias for `Man`, such as: `import SuperMan from 'Animals.js'` – starriet Mar 26 '22 at 02:30
  • 1
    Named imports are **not destructuring assignments**. Were it destructuring, renaming the import wouldn't be done using `as` but using `import { module: myModuleName } from ...`. – connexo Mar 26 '22 at 14:44
4
import { elements, renderLoader } from './views/base'

is the way you need to import single, named exports from a module, in this case it is importing named exports elements and renderLoader from base.js.

The { elements, renderLoader } syntax is in many cases just syntactic sugar (called destructuring) added in recent versions of the ECMAScript standard.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Object_destructuring

In this case, though, it is necessary to get only the named exports you want.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#Import_a_single_export_from_a_module

Please note that you can also pick new names for your variables like this:

import { elements as newNameForElements, renderLoader as newNameForRenderLoader } from './views/base'

which would then make the elements export available as newNameForElements etc.

connexo
  • 53,704
  • 14
  • 91
  • 128
  • 2
    This is totally incorrect! `import { elements, renderLoader } from './views/base'` is not the same as doing `import elements from './views/base'; import renderLoader from './views/base'`. If you haven't default exported `elements` or `renderLoader` then both the variables would be `undefined` in the second case. You have to pick them up using currly braces for proper import like so: `import {elements} from './views/base'; import {renderLoader} from './views/base'`. – UtkarshPramodGupta Aug 06 '18 at 07:20
  • @UtkarshPramodGupta Thanks for the heads up. Your are totally correct and I tried to delete my answer (which wasn't possible since it was the accepted answer), so I have corrected my answer accordingly. Please re-check and reconsider your downvote. – connexo Aug 06 '18 at 07:59
  • I did :) Mind my answer for more clarifications on export and imports in ES6. – UtkarshPramodGupta Aug 06 '18 at 08:28
3
import Search from './models/Search';

Imports the default exported element as Search.

import * as searchView from './views/searchView';

Imports everything into searchView that has been exported.

import { elements, renderLoader } from './views/base'

Imports a hand-picked number of named exported elements.

fjc
  • 5,590
  • 17
  • 36
2

{} is used when you want to import part of an object. The * as searchView one will import all properties and methods in the searchView file.

Suppose './views/base' has 3 properties: elements, renderLoader, additionalParam (Assuming that all three have been exported as named exports in the file)

When doing

import { elements, renderLoader } from './views/base'

you import only those 2 specific properties

But when you do

import * as base from './views/base'

you import all three properties in the object named base

Saransh Kataria
  • 1,447
  • 12
  • 19
1

Take the following example:

File to be imported, say importedFile.js:

var defaultExport, otherExport1, otherExport2, otherExport3;

export default defaultExport = () => {
    console.log("Default Export")
}

export otherExport1 = "Other non-default Export";

export otherExport2 = function() {
  console.log("Some more non-default Export");
};

export otherExport3 = { msg: "again non-default Export" };

Now in your main JS file, if you would do the following:

import something from './importedFile.js;

Here the variable something would get the value of the variable/function that has been exported as default in the importedFile.js file, i.e. the variable defaultExport. Now, if you do something like the following:

import { otherExport1, otherExport2 } from './importedFile.js;

It would import specifically otherExport1 and otherExport2 variable and function and not the defaultExport and otherExport3.

You can also do something like the following to import all the variables by their names from importedFile.js:

import { defaultExport, otherExport1, otherExport2, otherExport3 } from './importedFile.js';

Conclusion:

  1. curly braces are used to choose variables/functions/objects (using a technique called object destructuring in ES6) that need to be imported without importing all the other unnecessary exported variables/functions/objects.
  2. If you don't specify curly braces, it would always import only the variable/function/object that has been exported as default and nothing else. It would import undefined if nothing has been exported as default export.
UtkarshPramodGupta
  • 7,486
  • 7
  • 30
  • 54
0

You can use curly braces to import implicitly and selectively from another module functions or objects and so on.

// import implicitly one function and one constant from example.js
import { a, b } from 'example'

example.js

// export a and b but kept c private to example.js
export const a => { ... }
export const b = "hello"
const c = "private, not visible to the outside"

More infos: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import

https://developer.mozilla.org/en-US/docs/web/javascript/reference/statements/export

GibboK
  • 71,848
  • 143
  • 435
  • 658
0

If something is exported as default it is imported without curly braces.

If multiple variables are exported it is imported using curly braces.

For example,

in somefunction.js

export default module;

import module from './somefunction.js';

in someOtherFunction.js

export func1;

export func2;

import { func1, func2 }  from './someOtherFunction.js'
Anshul Bansal
  • 1,833
  • 1
  • 13
  • 12
0

You can export more than 1 content from a single module.

For example at your code:

import * as searchView from './views/searchView'; //1
import { elements, renderLoader } from './views/base' //2

At //1, you import Everything from './views/searchView';

At //2, there might be more content from './views/base', but you import only elements and renderLoader

For more information: import MDN

Jacky
  • 2,924
  • 3
  • 22
  • 34