Quand dois-je utiliser des accolades pour l'importation ES6?

767

Cela semble évident, mais je me suis senti un peu confus quant au moment d'utiliser des accolades pour importer un seul module dans ES6. Par exemple, dans le projet React-Native sur lequel je travaille, j'ai le fichier suivant et son contenu:

initialState.js
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;

Dans le TodoReducer.js, je dois l'importer sans accolades:

import initialState from './todoInitialState';

Si j'entoure les initialStateaccolades, j'obtiens l'erreur suivante pour la ligne de code suivante:

Impossible de lire la propriété todo de undefined

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

Des erreurs similaires se produisent également sur mes composants avec les accolades. Je me demandais quand utiliser des accolades pour une seule importation, car évidemment, lors de l'importation de plusieurs composants / modules, vous devez les mettre entre accolades, ce que je sais.

Éditer:

Le message SO ici ne répond pas à ma question, au lieu de cela, je demande quand je dois ou ne dois pas utiliser d'accolades pour importer un seul module, ou je ne devrais jamais utiliser d'accolades pour importer un seul module dans ES6 (ce n'est apparemment pas le cas, comme je l'ai vu l'importation unique avec des accolades bouclés requis)

TonyGW
la source
Copie
1
non, c'est différent. merci
TonyGW

Réponses:

2273

Il s'agit d'une importation par défaut :

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

Cela ne fonctionne que si Aa l' exportation par défaut :

// A.js
export default 42

Dans ce cas, peu importe le nom que vous lui attribuez lors de l'importation:

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

Parce qu'il résoudra toujours ce qui est l' exportation par défaut de A.


Il s'agit d'une importation nommée appeléeA :

import { A } from './A'

Cela ne fonctionne que si Acontient une exportation nommée appeléeA :

export const A = 42

Dans ce cas, le nom est important car vous importez une chose spécifique par son nom d'exportation :

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

Pour que cela fonctionne, vous devez ajouter une exportation nommée correspondante à A:

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

Un module ne peut avoir qu'une seule exportation par défaut , mais autant d'exportations nommées que vous le souhaitez (zéro, un, deux ou plusieurs). Vous pouvez les importer tous ensemble:

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

Ici, nous importons l'exportation par défaut en tant que A, et les exportations nommées appelées myAet Something, respectivement.

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

Nous pouvons également leur attribuer des noms différents lors de l'importation:

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

Les exportations par défaut ont tendance à être utilisées pour tout ce que vous attendez normalement du module. Les exportations nommées ont tendance à être utilisées pour des utilitaires qui peuvent être utiles, mais pas toujours nécessaires. Cependant, c'est à vous de choisir comment exporter les choses: par exemple, un module peut n'avoir aucune exportation par défaut.

Il s'agit d'un excellent guide des modules ES, expliquant la différence entre les exportations par défaut et les exportations nommées.

Dan Abramov
la source
4
Y a-t-il un inconvénient à ce qu'un module comporte des exportations individuelles export const myA = 43; export const Something = 44;ainsi qu'un export default { myA, Something }? Donc, lorsque vous importez, vous pouvez soit import A from './A';pour tout dans le module, soit import { Something } from './A';vous ne recevez qu'une partie du module
Michael
12
Il est très bien, mais il y a déjà une syntaxe pour saisir toutes les exportations nommées en un seul objet: import * as AllTheThings.
Dan Abramov
82
Clairement expliqué! Je souhaite pouvoir doubler voter cette réponse.
Willa
7
Qu'en est-il de cela import 'firebase/storage';ou import 'rxjs/add/operator/map';. Qu'est-ce que cela fait réellement?
kyw
9
@kyw: Ceci exécute le module mais ignore la valeur exportée. Utile pour les effets secondaires.
Dan Abramov
84

Je dirais qu'il y a aussi une notation étoilée pour le importmot-clé ES6 qui mérite d'être mentionnée.

entrez la description de l'image ici

Si vous essayez de consoler le mixage de journaux:

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

Tu auras:

entrez la description de l'image ici

Quand dois-je utiliser des accolades pour l'importation ES6?

Les supports sont dorés lorsque vous n'avez besoin que de composants spécifiques du module, ce qui réduit l'encombrement des bundlers comme webpack.

prosti
la source
4
Votre image est la feuille de triche parfaite pour cette réponse particulière.
Rodrirokr
1
Sont import * as Mix from "./A";et import A as Mix from "./A";les mêmes?
Shafizadeh
40

La réponse de Dan Abramov ci-dessus explique les exportations par défaut et les exportations nommées .

Lequel utiliser?

Citant David Herman : ECMAScript 6 favorise le style d'exportation unique / par défaut et donne la syntaxe la plus douce pour importer la valeur par défaut. L'importation d'exportations nommées peut et même devrait être légèrement moins concise.

Cependant, dans TypeScript, l'exportation nommée est favorisée en raison de la refactorisation. Par exemple, si vous exportez par défaut une classe et la renommez, le nom de la classe ne changera que dans ce fichier et pas dans les autres références, avec le nom de la classe exports nommé sera renommé dans toutes les références. Les exportations nommées sont également préférées pour les services publics.

Utilisez globalement ce que vous préférez.

Additionnel

L'exportation par défaut est en fait une exportation nommée avec un nom par défaut, donc l'exportation par défaut peut être importée en tant que:

import {default as Sample} from '../Sample.js';
Deepak Sharma
la source
2
La Additionalligne est une bonne information. import A from './A'n'a pas de sens si vous exportez sans définir un nom comme export default 42.
PGT
8
Veuillez vous assurer de ne pas mal interpréter la citation de David Herman. Cela ne signifie pas « Il est préférable de toujours utiliser les exportations uniques / par défaut dans ES6 », mais plutôt « Parce que les exportations uniques sont si courantes, ES6 prend mieux en charge les valeurs par défaut et nous leur avons donné la syntaxe la plus douce ».
Bergi
15

Si vous pensez importque le sucre de syntaxe est juste pour les modules de nœuds, les objets et la déstructuration, je trouve que c'est assez intuitif.

// 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' // same thing, object functionA and functionB props


// just one prop 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';
Brandon
la source
9

Pour comprendre l'utilisation des accolades dans les importinstructions, vous devez d'abord comprendre le concept de destruction introduit dans ES6

  1. Déstructuration d'objets

    var bodyBuilder = {
      firstname: 'Kai',
      lastname: 'Greene',
      nickname: 'The Predator'
    };
    
    var {firstname, lastname} = bodyBuilder;
    console.log(firstname, lastname); //Kai Greene
    
    firstname = 'Morgan';
    lastname = 'Aste';
    
    console.log(firstname, lastname); // Morgan Aste
  2. Déstructuration des baies

    var [firstGame] = ['Gran Turismo', 'Burnout', 'GTA'];
    
    console.log(firstGame); // Gran Turismo

    Utilisation de la correspondance de liste

      var [,secondGame] = ['Gran Turismo', 'Burnout', 'GTA'];
      console.log(secondGame); // Burnout

    Utilisation de l'opérateur d'étalement

    var [firstGame, ...rest] = ['Gran Turismo', 'Burnout', 'GTA'];
    console.log(firstGame);// Gran Turismo
    console.log(rest);// ['Burnout', 'GTA'];

Maintenant que nous avons cela hors de notre chemin, dans ES6 vous pouvez exporter plusieurs modules. Vous pouvez ensuite utiliser la déstructuration d'objets comme ci-dessous

Supposons que vous ayez un module appelé module.js

    export const printFirstname(firstname) => console.log(firstname);
    export const printLastname(lastname) => console.log(lastname);

Vous souhaitez importer les fonctions exportées dans index.js;

    import {printFirstname, printLastname} from './module.js'

    printFirstname('Taylor');
    printLastname('Swift');

Vous pouvez également utiliser différents noms de variables comme ceci

    import {printFirstname as pFname, printLastname as pLname} from './module.js'

    pFname('Taylor');
    pLanme('Swift');
theTypan
la source
Puisque vous montrez des comparaisons avec la déstructuration, j'ajouterais la comparaison de déstructuration équivalente à votre dernier commentaire: import {printFirstname as pFname, printLastname as pLname} from './module.js'équivaut à:var foo = {printFirstname: 'p_f_n', printLastname: 'p_l_n'}; var { printFirstname:pFname, printLastname: pLname } = foo; pFname('Taylor'); pLname('Swift');
Adam Moisa
fan de musculation?
Tushar Pandey
@TusharPandey Je suis un
culturiste
1
Je pense que dans toute explication de l'importation et quand utiliser des curlys vs ne pas les utiliser, si vous ne mentionnez pas la destruction d'objets, vous ne donnez vraiment pas la meilleure explication. Une fois que j'ai appris la déstructuration, je n'ai plus pensé à la raison pour laquelle j'utilisais le bouclé, cela avait simplement un sens intuitif.
Eric Bishard
6

ES6Modules récapitulatifs :

exportations:

Vous avez 2 types d'export:

  1. Exportations nommées
  2. Exportations par défaut, max 1 par module

Syntaxe:

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

Importations:

Le type d'exportation (c'est-à-dire les exportations nommées ou par défaut) affecte la façon d'importer quelque chose:

  1. Pour une exportation nommée, nous devons utiliser des accolades et le nom exact comme déclaration (c'est-à-dire variable, fonction ou classe) qui a été exportée.
  2. Pour une exportation par défaut, nous pouvons choisir le nom.

Syntaxe:

// 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';   

Choses d'intérêt:

  1. Utilisez une liste séparée par des virgules entre accolades avec le nom correspondant de l'exportation pour l'exportation nommée.
  2. Utilisez un nom de votre choix sans accolades pour une exportation par défaut.

Alias:

Chaque fois que vous souhaitez renommer une importation nommée, cela est possible via des alias . La syntaxe est la suivante:

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

Maintenant, nous avons importé importantData_1 mais l'identifiant est à la myDataplace de importantData_1.

Willem van der Veen
la source
5

généralement, lorsque vous exportez une fonction, vous devez utiliser le {}

if you have export const x 

tu utilises import {x} from ''

if you use export default const x 

vous devez utiliser import X from '' ici, vous pouvez changer X pour n'importe quelle variable que vous voulez

jadlmir
la source
4

Les accolades ({}) sont utilisées pour importer des liaisons nommées et le concept derrière cela est la déstructuration de l'affectation

Une démonstration simple du fonctionnement de la déclaration d'importation avec un exemple peut être trouvée dans ma propre réponse à une question similaire sur Quand utilisons-nous '{}' dans les importations javascript?

samuelj90
la source
1
vous obtenez certainement mon vote pour la meilleure réponse courte!
Eric Bishard
0

Les accolades sont utilisées uniquement pour l'importation lorsque l'exportation est nommée. Si l'exportation est par défaut, les accolades ne sont pas utilisées pour l'importation.

Abhishek Kumar
la source
0

Pour une exportation par défaut, nous n'utilisons pas {} lors de l'importation.

par exemple

player.js

export default vx;

index.js

import vx from './player';

index.js entrez la description de l'image ici

player.js entrez la description de l'image ici

Si nous voulons importer tout ce que nous exportons, nous utilisons * entrez la description de l'image ici

user260778
la source