usando colchetes com sintaxe de importação javascript

115

Encontrei uma biblioteca javascript que usa a seguinte sintaxe para importar bibliotecas:

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

Qual é a diferença entre o método acima e o seguinte?

import React, Component, PropTypes from 'react';
Raposa
fonte
4
A resposta está na documentação
adeneo
4
Os membros a serem importados do módulo são colocados entre chaves
adeneo
1
Ha. Se eliminássemos todas as vezes, seria possível responder a uma pergunta SO com "RTFM", mesmo Jon Skeet poderia ter menos de seis dígitos. ; ^)
ruffin de

Respostas:

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

Isso diz:

Importe a exportação padrão'react' com o nome Reacte importe as exportações nomeadasComponent e PropTypescom os mesmos nomes.

Isso combina as duas sintaxes comuns que você provavelmente já viu

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

O primeiro sendo usado para importar e nomear a exportação padrão, o segundo para importar as exportações nomeadas especificadas.

Como regra geral, a maioria dos módulos fornecerá uma exportação única padrão ou uma lista de exportações nomeadas. É um pouco menos comum para um módulo fornecer uma exportação padrão e exportações nomeadas. No entanto, no caso em que há um recurso que é mais comumente importado, mas também sub-recursos adicionais, é um design válido exportar o primeiro como o padrão e os restantes como exportações nomeadas. É nesses casos que você usaria a importsintaxe à qual se refere.

As outras respostas estão entre erradas e confusas, possivelmente porque os documentos MDN no momento em que esta pergunta foi feita estavam errados e confusos. MDN mostrou o exemplo

import name from "module-name";

e dito nameé o "nome do objeto que receberá os valores importados." Mas isso é enganoso e incorreto; em primeiro lugar, há apenas um valor de importação, que será "recebido" (por que não dizer apenas "atribuído a" ou "usado para se referir a") name, e o valor de importação neste caso é a exportação padrão do módulo .

Outra maneira de explicar isso é observar que a importação acima é precisamente idêntica a

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

e o exemplo do OP é precisamente idêntico ao

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

A documentação MDN passou a mostrar o exemplo

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

e afirmou que significa

Importe o conteúdo de um módulo inteiro, alguns também sendo nomeados explicitamente. Isso insere myModule(sic) foo, e barno escopo atual. Observe que fooe myModule.foosão iguais, assim como são baremyModule.bar

O que o MDN disse aqui e o que outras respostas afirmam com base na documentação incorreta do MDN estão absolutamente errados e podem ser baseados em uma versão anterior da especificação. O que isso realmente faz é

Importe a exportação de módulo padrão e algumas exportações nomeadas explicitamente. Isso insere MyModule, fooe barno escopo atual. Os nomes de exportação fooe nãobar estão acessíveis viaMyModule , que é a exportação padrão , e não um guarda-chuva que cobre todas as exportações.

(A exportação de módulo padrão é o valor exportado com a export defaultsintaxe, que também pode ser export {foo as default}.)

Os escritores da documentação MDN podem ter se confundido com a seguinte forma:

import * as MyModule from 'my-module';

Isso importa todas as exportações de my-modulee as torna acessíveis com nomes como MyModule.name. A exportação padrão também está acessível como MyModule.default, uma vez que a exportação padrão nada mais é do que outra exportação nomeada com o nome default. Nesta sintaxe, não há como importar apenas um subconjunto das exportações nomeadas, embora seja possível importar a exportação padrão, se houver, junto com todas as exportações nomeadas, com

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

fonte
1
Babel aceita from '/path/to/my-module.js', embora eu pessoalmente use from '/path/to/my-module'.
royhowie
5
Com essa explicação detalhada, você também deve adicionar como eles são exportados para serem importados dessa forma.
Caio Iglesias
37
import React, { Component, PropTypes } from 'react'

Isso pegará os { Component, PropTypes }membros exportados do 'react'módulo e os atribuirá a Componente PropTypes, respectivamente. Reactserá igual ao do módulodefault exportação .

Conforme observado por torazaburo abaixo , este é o mesmo que

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

que é uma abreviatura para

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

Aqui está outro exemplo ( link para a essência ):

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

Testei o segundo exemplo com babel:

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

e obteve um erro de sintaxe.

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

Para referência, você pode ler sobre a nova importdocumentação do MDN. No entanto, ele aparentemente precisa de uma revisão técnica.A postagem do blog do Dr. Axel Rauschmayer é uma referência melhor por enquanto.

royhowie
fonte
1
Isso pegará as propriedades {Component, PropTypes} das exportações no módulo 'react' e as atribuirá ao React. Isso está incorreto. Ele atribui a exportação padrão Reacte as exportações nomeadas Componente PropTypesvariáveis ​​com o mesmo nome. Infelizmente, os documentos MDN estão errados, como você descobriria se tentasse. Consulte 2ality.com/2014/09/es6-modules-final.html . Além disso, a sintaxe de importação não tem absolutamente nada a ver com atribuição de desestruturação.
3
Com relação ao seu comentário sobre a "nova importdocumentação", revisando o histórico de revisão daquele artigo MDN, as partes que você está citando não foram revisadas desde que a página foi escrita pela primeira vez há mais de um ano, um período durante o qual a sintaxe do módulo foi mudando rapidamente.
1
@torazaburo Reescrevi minha resposta para ser mais precisa.
royhowie
@royhowie Muito obrigado por este exemplo !! Literalmente economizou mais uma hora de navegar sem pensar ... Só tenho uma pergunta. Em example3.jspor que ele imprimir undefinedpara console.log(d)? Depois de fazer export default { a, b, d }isso, você o exportou para myModule.js.
CapturedTree
2
@ 1290 Em myModule.js, nota que a, be cforam exportados individualmente. Isso significa que outro arquivo pode importá-los diretamente com import { a } from 'myModule'. Por outro lado, dsó está disponível por meio da exportação padrão, portanto outro módulo pode acessá-lo de duas formas: import thisObjectContainsDefault from 'myModule'e acessá-lo via thisObjectContainsDefault.dOR import { default as wrapperObject }e wrapperObject.d. O benefício da segunda abordagem é que você também pode obter itens que foram exportados individualmente, como pode ser visto em example3.js.
royhowie