utilizzando le parentesi con la sintassi di importazione javascript


115

Mi sono imbattuto in una libreria javascript che utilizza la seguente sintassi per importare le librerie:

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

Qual è la differenza tra il metodo sopra e il seguente?

import React, Component, PropTypes from 'react';

4
La risposta è nella documentazione
adeneo

4
I membri da importare dal modulo sono racchiusi tra parentesi graffe
adeneo


1
Ha. Se eliminassimo tutte le volte si potrebbe probabilmente rispondere a una domanda SO con "RTFM", anche Jon Skeet potrebbe avere meno di sei cifre. ; ^)
ruffin

Risposte:


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

Questo dice:

Importa l' esportazione predefinita da 'react'sotto il nome Reacte importa le esportazioni denominateComponent e PropTypescon gli stessi nomi.

Questo combina le due sintassi comuni che probabilmente hai visto

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

Il primo utilizzato per importare e denominare l'esportazione predefinita, il secondo per importare le esportazioni denominate specificate.

Come regola generale, la maggior parte dei moduli fornirà una singola esportazione predefinita o un elenco di esportazioni con nome. E 'un po' meno del solito per un modulo per fornire sia un export di default e le esportazioni di nome. Tuttavia, nel caso in cui vi sia una funzionalità che viene importata più comunemente, ma anche funzionalità secondarie aggiuntive, è un progetto valido esportare la prima come predefinita e le rimanenti come esportazioni con nome. È in questi casi che useresti la importsintassi a cui ti riferisci.

Le altre risposte sono da qualche parte tra sbagliato e confuso, probabilmente perché i documenti MDN al momento in cui è stata posta questa domanda erano sbagliati e confusi. MDN ha mostrato l'esempio

import name from "module-name";

e ha detto nameè il "nome dell'oggetto che riceverà i valori importati". Ma questo è fuorviante e sbagliato; prima di tutto, c'è un solo valore di importazione, che sarà "ricevuto" (perché non dire semplicemente "assegnato a" o "usato per fare riferimento a") name, e il valore di importazione in questo caso è l' esportazione predefinita dal modulo .

Un altro modo per spiegare questo è notare che l'importazione di cui sopra è esattamente identica a

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

e l'esempio dell'OP è esattamente identico a

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

La documentazione MDN ha continuato a mostrare l'esempio

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

e ha affermato che significa

Importa il contenuto di un intero modulo, con alcuni anche esplicitamente nominati. Questo inserisce myModule(sic) foo, e barnel campo di applicazione corrente. Nota che fooe myModule.foosono la stessa cosa, come lo sono baremyModule.bar

Ciò che MDN ha detto qui, e quali altre risposte affermano in base alla documentazione MDN errata, è assolutamente sbagliato e potrebbe essere basato su una versione precedente della specifica. Ciò che in realtà fa è

Importa l'esportazione del modulo predefinito e alcune esportazioni dal nome esplicito. Questo inserisce MyModule, fooe barnell'ambito corrente. I nomi di esportazione fooe nonbar sono accessibili tramiteMyModule , che è l' esportazione predefinita , non un ombrello che copre tutte le esportazioni.

(L'esportazione del modulo predefinito è il valore esportato con la export defaultsintassi, che potrebbe anche essere export {foo as default}.)

Gli autori della documentazione MDN potrebbero essersi confusi con il seguente modulo:

import * as MyModule from 'my-module';

Ciò importa tutte le esportazioni da my-modulee le rende accessibili con nomi come MyModule.name. L'esportazione predefinita è accessibile anche come MyModule.default, poiché l'esportazione predefinita non è altro che un'altra esportazione denominata con il nome default. In questa sintassi, non è possibile importare solo un sottoinsieme delle esportazioni denominate, sebbene si possa importare l'esportazione predefinita, se presente, insieme a tutte le esportazioni denominate, con

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

1
Babel accetta from '/path/to/my-module.js', anche se personalmente uso from '/path/to/my-module'.
royhowie

5
Con una spiegazione così dettagliata dovresti anche aggiungere come vengono esportati per essere importati in questo modo.
Caio Iglesias

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

Questo catturerà i { Component, PropTypes }membri esportati dal 'react'modulo e li assegnerà a Componente PropTypes, rispettivamente. Reactsarà uguale defaultall'esportazione del modulo .

Come notato da torazaburo di seguito , questo è lo stesso di

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

che è una scorciatoia per

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

Ecco un altro esempio ( collegamento al sommario ):

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

Ho provato il secondo esempio con Babel:

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

e ha ricevuto un errore di sintassi.

~/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 | 

Per riferimento, puoi leggere la nuova importdocumentazione di MDN. Tuttavia, a quanto pare necessita di una revisione tecnica. Il post sul blog del Dr. Axel Rauschmayer è un riferimento migliore per ora.


1
Questo prenderà le proprietà {Component, PropTypes} dalle esportazioni nel modulo 'react' e le assegnerà a React. Questo non è corretto. Assegna l'esportazione predefinita a React, e le esportazioni denominate Componente PropTypesalle variabili con lo stesso nome. Sfortunatamente, i documenti MDN sono sbagliati, come scopriresti se lo provassi. Vedi 2ality.com/2014/09/es6-modules-final.html . Inoltre, la sintassi di importazione non ha assolutamente nulla a che fare con l'assegnazione destrutturante.

3
Per quanto riguarda il tuo commento sulla "nuova importdocumentazione", rivedendo la cronologia delle revisioni di quell'articolo MDN, le parti che stai citando non sono state riviste da quando la pagina è stata scritta per la prima volta più di un anno fa, un periodo durante il quale la sintassi del modulo era cambiando rapidamente.

1
@torazaburo ho riscritto la mia risposta per essere più precisa.
royhowie

@royhowie Grazie mille per questo esempio !! Ho letteralmente risparmiato un'altra ora per sfogliare senza cervello ... Ho solo una domanda. Nel example3.jsPerché è stampare undefinedper console.log(d)? Dato che l'hai fatto export default { a, b, d }, l'hai esportato in myModule.js.
CapturedTree

2
@ 1290 In myModule.js, nota che a, be csono stati esportati singolarmente. Ciò significa che un altro file può importarli direttamente con import { a } from 'myModule'. D'altra parte, dè disponibile solo tramite l'esportazione predefinita, quindi un altro modulo può accedervi in ​​due modi: import thisObjectContainsDefault from 'myModule'e accedervi tramite thisObjectContainsDefault.dOR import { default as wrapperObject }e wrapperObject.d. Il vantaggio del secondo approccio è che puoi anche prendere oggetti che sono stati esportati individualmente, come si può vedere in example3.js.
royhowie
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.