utilisation de crochets avec la syntaxe d'importation javascript

115

Je suis tombé sur une bibliothèque javascript qui utilise la syntaxe suivante pour importer des bibliothèques:

import React, { Component, PropTypes } from 'react';

Quelle est la différence entre la méthode ci-dessus et la suivante?

import React, Component, PropTypes from 'react';
Renard
la source
4
La réponse est dans la documentation
adeneo
4
Les membres à importer du module sont enfermés dans des accolades
adeneo
1
Ha. Si nous éliminions tous les temps, on pourrait sans doute répondre à une question SO avec "RTFM", même Jon Skeet pourrait avoir moins de six chiffres. ; ^)
ruffin

Réponses:

174
import React, { Component, PropTypes } from 'react';

Cela dit:

Importez l' exportation par défaut de 'react'sous le nom Reactet importez les exportations nomméesComponent et PropTypessous les mêmes noms.

Cela combine les deux syntaxes courantes que vous avez probablement vues

import React from 'react';
import { Component, PropTypes } from 'react';

Le premier étant utilisé pour importer et nommer l'exportation par défaut, le second pour importer les exportations nommées spécifiées.

En règle générale, la plupart des modules fourniront soit une seule exportation par défaut, soit une liste d'exportations nommées. Il est un peu moins habituel pour un module de fournir à la fois une exportation par défaut et des exportations nommées. Cependant, dans le cas où il existe une fonctionnalité qui est le plus souvent importée, mais également des sous-fonctionnalités supplémentaires, il est possible d'exporter la première par défaut et les autres en tant qu'exportations nommées. C'est dans ce cas que vous utiliserez la importsyntaxe à laquelle vous faites référence.

Les autres réponses sont quelque part entre fausses et déroutantes, peut-être parce que les documents MDN à l'époque où cette question a été posée étaient faux et déroutants. MDN a montré l'exemple

import name from "module-name";

et dit nameest le "nom de l'objet qui recevra les valeurs importées". Mais c'est trompeur et incorrect; tout d'abord, il n'y a qu'une seule valeur d'importation, qui sera "reçue" (pourquoi ne pas simplement dire "assignée à", ou "utilisée pour faire référence à") name, et la valeur d'importation dans ce cas est l' exportation par défaut du module .

Une autre façon d'expliquer cela est de noter que l'importation ci-dessus est exactement identique à

import { default as name } from "module-name";

et l'exemple de l'OP est exactement identique à

import { default as React, Component, PropTypes } from 'react';

La documentation MDN a continué pour montrer l'exemple

import MyModule, {foo, bar} from "my-module.js";

et a affirmé que cela signifie

Importez le contenu d'un module entier, certains étant également explicitement nommés. Cela insère myModule(sic) foo, et bardans la portée actuelle. Notez que fooet myModule.foosont les mêmes, que sont baretmyModule.bar

Ce que MDN a dit ici, et ce que d'autres réponses prétendent sur la base d'une documentation MDN incorrecte, est absolument faux et peut être basé sur une version antérieure de la spécification. Ce que cela fait réellement, c'est

Importez l'exportation du module par défaut et certaines exportations nommées explicitement. Cela insère MyModule, fooet bardans la portée actuelle. Les noms d'exportation fooet nebar sont pas accessibles viaMyModule , qui est l' exportation par défaut , pas un parapluie couvrant toutes les exportations.

(L'exportation de module par défaut est la valeur exportée avec la export defaultsyntaxe, ce qui pourrait également l'être export {foo as default}.)

Les rédacteurs de la documentation MDN peuvent avoir été confondus avec le formulaire suivant:

import * as MyModule from 'my-module';

Cela importe toutes les exportations de my-moduleet les rend accessibles sous des noms tels que MyModule.name. L'exportation par défaut est également accessible en tant que MyModule.default, puisque l'exportation par défaut n'est en réalité rien de plus qu'une autre exportation nommée avec le nom default. Dans cette syntaxe, il n'y a aucun moyen d'importer uniquement un sous-ensemble des exportations nommées, bien que l'on puisse importer l'exportation par défaut, s'il y en a une, avec toutes les exportations nommées, avec

import myModuleDefault, * as myModule from 'my-module';

la source
1
Babel accepte from '/path/to/my-module.js', bien que j'utilise personnellement from '/path/to/my-module'.
royhowie
5
Avec une explication aussi détaillée, vous devez également ajouter comment ils sont exportés afin d'être importés comme ça.
Caio Iglesias
37
import React, { Component, PropTypes } from 'react'

Cela récupérera les { Component, PropTypes }membres exportés du 'react'module et les affectera respectivement à Componentet PropTypes. Reactsera égal à l' defaultexportation du module .

Comme indiqué par torazaburo ci - dessous , c'est la même chose que

import { default as React, Component, PropTypes } from 'react'

qui est un raccourci pour

import { default as React, Component as Component, PropTypes as PropTypes} from 'react'

Voici un autre exemple ( lien vers l'essentiel ):

// myModule.js
export let a = true
export let b = 42
export let c = 'hello, world!'
// `d` is not exported alone
let d = 'some property only available from default'

// this uses the new object literal notation in es6
// {myVar} expands to { myVar : myVar }, provided myVar exists
// e.g., let test = 22; let o = {test}; `o` is then equal to { test : 22 }
export default { a, b, d }

// example1.js
import something from 'myModule'
console.log(something)
// this yields (note how `c` is not here):
/*
  {
    a : true,
    b : 42,
    d : 'some property only available from default'
  }
*/

// example2.js
import something, { c } from 'myModule'
console.log(something)  // same as above; the `default` export
console.log(c)          // c === 'hello, world!'

// example3.js
import { a, b, d, default as something } from 'myModule'
console.log(a)            // a === true
console.log(b)            // b === 42
console.log(d)            // d === undefined (we didn't export it individually)
console.log(something.d)  // something.d === 'some property...'

J'ai testé le deuxième exemple avec babel:

import test, test3, test2 from './app/lib/queries.js'
console.log(test, test3, test2)

et a obtenu une erreur de syntaxe.

~/code/repo/tutoring $ babel-node test.js
/Users/royhowie/.node/lib/node_modules/babel/node_modules/babel-core/lib/babel/transformation/file/index.js:601
      throw err;
            ^
SyntaxError: /Users/royhowie/code/repo/tutoring/test.js: Unexpected token (1:13)
> 1 | import test, test3, test2 from './app/lib/queries.js'
    |              ^
  2 | 
  3 | console.log(test, test3, test2)
  4 | 

Pour référence, vous pouvez consulter la nouvelle importdocumentation de MDN. Cependant, il a apparemment besoin d'un examen technique. Le billet de blog du Dr Axel Rauschmayer est une meilleure référence pour le moment.

Royhowie
la source
1
Cela récupérera les propriétés {Component, PropTypes} des exportations dans le module 'react' et les affectera à React. Ceci est une erreur. Il attribue l'exportation par défaut à React, et les exportations nommées Componentet PropTypesà des variables de même nom. Malheureusement, les documents MDN sont erronés, comme vous le découvririez si vous les essayiez. Voir 2ality.com/2014/09/es6-modules-final.html . De plus, la syntaxe d'importation n'a absolument rien à voir avec l'affectation de déstructuration.
3
En ce qui concerne votre commentaire sur la "nouvelle importdocumentation", en passant en revue l'historique des révisions de cet article MDN, les parties que vous citez n'ont pas été révisées depuis la création de la page il y a plus d'un an, période pendant laquelle la syntaxe du module était change rapidement.
1
@torazaburo J'ai réécrit ma réponse pour être plus précise.
royhowie
@royhowie Merci beaucoup pour cet exemple !! Littéralement sauvé une autre heure de navigation stupide ... J'ai juste une question. Dans example3.jspourquoi at - il imprimer undefinedpour console.log(d)? Depuis que vous l'avez fait export default { a, b, d }, vous l'avez exporté au format myModule.js.
CapturedTree
2
@ Dans 1290 myModule.js, notez que a, bet cont été exportés individuellement. Cela signifie qu'un autre fichier peut les importer directement avec import { a } from 'myModule'. D'autre part, dn'est disponible que via l'exportation par défaut, donc un autre module peut y accéder de deux manières: import thisObjectContainsDefault from 'myModule'et y accéder via thisObjectContainsDefault.dOR import { default as wrapperObject }et wrapperObject.d. L'avantage de la deuxième approche est que vous pouvez également récupérer des éléments qui ont été exportés individuellement, comme on peut le voir dans example3.js.
royhowie