¿Cuándo debo usar llaves para importar ES6?


Parece obvio, pero me encontré un poco confundido sobre cuándo usar llaves para importar un solo módulo en ES6. Por ejemplo, en el proyecto React-Native en el que estoy trabajando, tengo el siguiente archivo y su contenido:

Estado inicial.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;

En el TodoReducer.js, tengo que importarlo sin llaves:

import initialState from './todoInitialState';

Si encierro el initialState en llaves, obtengo el siguiente error para la siguiente línea de código:

No se puede leer la propiedad todo de undefined

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

Errores similares también ocurren a mis componentes con las llaves. Me preguntaba cuándo debería usar llaves para una sola importación, porque obviamente, al importar múltiples componentes / módulos, tienes que encerrarlos en llaves, lo cual sé.

Editar:

El post de SO en aquí no responde a mi pregunta, en cambio estoy preguntando cuando Debería o no usar llaves para importar un single module, o nunca debería usar llaves para importar un solo módulo en ES6 (aparentemente este no es el caso, ya que he visto que se requiere una sola importación con llaves)

Author: Mowzer, 2016-04-22

8 answers

Esta es una importación predeterminada :

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

Solo funciona si A tiene la exportación por defecto :

// A.js
export default 42

En este caso no importa qué nombre le asigne al importar:

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

Porque siempre se resolverá a lo que sea la exportación por defecto de A.


Esta es una importación llamada llamada A:

import { A } from './A'

Solo funciona si A contiene un llamado export called A:

export const A = 42

En este caso el nombre importa porque estás importando una cosa específica por su nombre de exportación :

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

Para hacer que estos funcionen, usted agregaría un correspondiente con nombre export a A:

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

Un módulo solo puede tener una exportación predeterminada, pero tantas exportaciones con nombre como desee (cero, uno, dos o muchos). Puedes importarlos todos juntos:

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

Aquí, importamos la exportación predeterminada como A, y las exportaciones denominadas myA y Something, respectivamente.

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

También podemos asignarles nombres diferentes al importar:

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

Las exportaciones predeterminadas tienden a usarse para lo que normalmente espera obtener del módulo. Las exportaciones con nombre tienden a usarse para utilidades que podrían ser útiles, pero no siempre son necesarias. Sin embargo, depende de usted elegir cómo exportar las cosas: por ejemplo, un módulo puede no tener una exportación predeterminada en todo.

Esta es una gran guía para los módulos ES, explicando la diferencia entre las exportaciones predeterminadas y con nombre.

 1380
Author: Dan Abramov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-30 15:08:59

TL; DR : Se usan llaves si desea importar una exportación no predeterminada.

Vea la respuesta de Dan Abramov para más detalles.

 85
Author: Daniel Schmidt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-28 14:50:45

Yo diría que también hay una notación con estrellas para la palabra clave import ES6 que vale la pena mencionar.

introduzca la descripción de la imagen aquí

Si intenta consolar log Mix:

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

Obtendrá:

introduzca la descripción de la imagen aquí

¿Cuándo debo usar llaves para importar ES6?

Los soportes son dorados cuando solo necesita componentes específicos del módulo, lo que hace que las huellas sean más pequeñas para los bundlers como webpack.

 52
Author: prosti,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-30 00:19:11

Dan Abramov respuesta anterior explica acerca de la exportaciones por defecto y exportaciones con nombre .

¿Cuál usar?

Citando a David Herman: ECMAScript 6 favorece el estilo de exportación único/predeterminado, y da la sintaxis más dulce para importar el predeterminado. Importar exportaciones con nombre puede e incluso debe ser un poco menos conciso.

Sin embargo, en TypeScript la exportación con nombre se ve favorecida debido a la refactorización. Ejemplo, si exporta por defecto una clase y cambia el nombre it, el nombre de la clase cambiará solo en ese archivo y no en las otras referencias, con las exportaciones con nombre el nombre de la clase se renombrará en todas las referencias. Las exportaciones con nombre también son preferidas para las utilidades.

Uso general lo que prefiera.

Adicional

La exportación predeterminada es en realidad una exportación con nombre por defecto, por lo que la exportación predeterminada se puede importar como:

import {default as Sample} from '../Sample.js';
 31
Author: Deepak Sharma,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-31 06:21:57

Si piensas en import como solo azúcar de sintaxis para módulos de nodos, objetos y desestructuración, me parece bastante intuitivo.

// 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';
 9
Author: Brandon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-30 03:44:58

En orden a entender el uso de llaves en import declaraciones, en primer lugar, usted tiene que entender el concepto de destruir introducido en ES6

  1. Desestructuración de objetos

    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. Matriz de desestructuración

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

    Usando la coincidencia de lista

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

    Usando el operador spread

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

Ahora que tenemos que salir de nuestro camino, en ES6 puede exportar múltiples módulos. A continuación, puede hacer uso de la desestructuración de objetos como a continuación

Supongamos que tienes un módulo llamado module.js

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

Desea importar las funciones exportadas a index.js;

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

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

También puede usar diferentes nombres de variables como so

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

    pFname('Taylor');
    pLanme('Swift');
 1
Author: theTypan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-07 08:33:07

Por lo general, cuando exporta una función, debe usar {}

if you have export const x 

Usted usa import {x} from ''

if you use export default const x 

Necesita usar import X from '' aquí puede cambiar X a cualquier variable que desee

 1
Author: jadlmir,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-07 14:43:09

Las llaves ({}) se utilizan para importar enlaces con nombre y el concepto detrás de él es la asignación de desestructuración

Una simple demostración de cómo funciona la instrucción import con un ejemplo se puede encontrar en mi propia respuesta a una pregunta similar en ¿Cuándo usamos '{ }' en las importaciones de javascript?

 0
Author: Samuel J Mathew,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-08 19:20:36