Búsqueda de sitios web

ecmascript 6 - uso de corchetes con la sintaxis de importación de javascript


Me encontré con una biblioteca javascript que utiliza la siguiente sintaxis para importar librerías:

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

¿Cuál es la diferencia entre el método anterior y el siguiente?

import React, Component, PropTypes from 'react';

Respuesta #1

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

Esto dice:

Importa la exportación por defecto de 'react' bajo el nombre React e importa las exportaciones nombradas Component y PropTypes bajo los mismos nombres.

Esto combina las dos sintaxis comunes que probablemente has visto

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

El primero se usa para importar y nombrar la exportación por defecto, el segundo para importar las exportaciones con nombre especificadas.

Como regla general, la mayoría de los módulos proporcionará ya sea una única exportación por defecto, o una lista de exportaciones nombradas. Es algo menos común que un módulo proporcione tanto una exportación por defecto como exportaciones nombradas. Sin embargo, en el caso de que exista una característica que se importe con más frecuencia, pero también haya subcaracterísticas adicionales, es un diseño válido exportar la primera como la por defecto, y las restantes como exportaciones nombradas. Es en tales casos cuando usarías la sintaxis import a la que te refieres.

Las otras respuestas están en algún lugar entre equivocadas y confusas, posiblemente porque los documentos de MDN en el momento en que se hizo esta pregunta estaban equivocados y eran confusos. MDN mostró el ejemplo

import name from "module-name";

y dijo que name es el "nombre del objeto que recibirá los valores importados." Pero eso es engañoso e incorrecto; en primer lugar, solo hay un valor de importación, que será "recibido" (¿por qué no decir simplemente "asignado a", o "usado para referirse a") name, y el valor de importación en este caso es la exportación predeterminada del módulo.

Otra forma de explicar esto es notar que la importación anterior es precisamente idéntica a

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

y el ejemplo del OP es precisamente idéntico a

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

La documentación de MDN continuó mostrando el ejemplo

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

y afirmó que significa

Importa todo el contenido de un módulo, con algunos también siendo nombrados explícitamente. Esto inserta myModule (sic), foo y bar en el ámbito actual. Nota que foo y myModule.foo son lo mismo, al igual que bar y myModule.bar

Lo que dijo MDN aquí, y lo que otras respuestas afirman basándose en la documentación incorrecta de MDN, es absolutamente incorrecto y puede estar basado en una versión anterior de la especificación. Lo que esto realmente hace es

Importa la exportación por defecto del módulo y algunas exportaciones nombradas explícitamente. Esto inserta MyModule, foo y bar en el alcance actual. Los nombres de exportación foo y bar no son accesibles a través de MyModule, que es la exportación por defecto, no un paraguas que cubra todas las exportaciones.

(El módulo exportado por defecto es el valor exportado con la sintaxis export default, que también podría ser export {foo as default}.)

Los redactores de la documentación de MDN pueden haberse confundido con la siguiente forma:

import * as MyModule from 'my-module';

Esto importa todas las exportaciones de my-module, y las hace accesibles bajo nombres como MyModule.name. La exportación por defecto también es accesible como MyModule.default, ya que la exportación por defecto no es más que otra exportación nombrada con el nombre default. En esta sintaxis, no hay manera de importar solo un subconjunto de las exportaciones nombradas, aunque se podría importar la exportación por defecto, si existe, junto con todas las exportaciones nombradas, con

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

Respuesta #2

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

Esto capturará los miembros exportados { Component, PropTypes } del módulo 'react' y los asignará a Component y PropTypes, respectivamente. React será igual a la exportación default del módulo.

Como señaló torazaburo más abajo, esto es lo mismo que

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

que es la abreviatura de

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

Aquí hay otro ejemplo (enlace al gist):

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

Probé el segundo ejemplo con Babel:

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

y obtuve un error de sintaxis.

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

Como referencia, puedes leer la nueva documentación de import en MDN. Sin embargo, aparentemente necesita una revisión técnica. La publicación en el blog del Dr. Axel Rauschmayer es una mejor referencia por ahora.

Artículos relacionados