`export const` vs.` export default` en ES6

204

Estoy tratando de determinar si hay grandes diferencias entre estos dos, además de poder importar con export defaultsolo hacer:

import myItem from 'myItem';

Y usando export constpuedo hacer:

import { myItem } from 'myItem';

Me pregunto si hay diferencias y / o casos de uso distintos a este.

ajmajmajma
fuente
1
El uso consthará que el identificador sea de solo lectura. Entonces, en el caso de valores primitivos, puede considerar que es inmutable. Tenga en cuenta que el valor en sí no es inmutable, por lo que los objetos, las matrices, etc. se pueden cambiar, pero no se pueden reasignar.
spmurrayzzz
44
@spmurrayzzz: FWIW, los enlaces de importación también son inmutables, al igual que const.
Felix Kling
gracias por la aclaración @FelixKling, no sabía eso
spmurrayzzz
@FelixKling: desde afuera, al menos. Sin embargo, pueden no ser constantes, las exportaciones se pueden cambiar.
Bergi
@Bergi: correcto, por eso dije enlaces de importación ;)
Felix Kling

Respuestas:

327

Es una exportación con nombre frente a una exportación predeterminada. export constes una exportación con nombre que exporta una declaración o declaraciones constantes.

Para enfatizar: lo que importa aquí es la exportpalabra clave que constse usa para declarar una declaración o declaraciones constantes. exporttambién se puede aplicar a otras declaraciones, como las declaraciones de clase o función.

Exportación predeterminada ( export default)

Puede tener una exportación predeterminada por archivo. Cuando importa tiene que especificar un nombre e importar así:

import MyDefaultExport from "./MyFileWithADefaultExport";

Puedes ponerle el nombre que quieras.

Exportación con nombre ( export)

Con exportaciones con nombre, puede tener múltiples exportaciones con nombre por archivo. Luego importe las exportaciones específicas que desee rodeadas de llaves:

// ex. importing multiple exports:
import { MyClass, MyOtherClass } from "./MyClass";
// ex. giving a named import a different name by using "as":
import { MyClass2 as MyClass2Alias } from "./MyClass2";

// use MyClass, MyOtherClass, and MyClass2Alias here

O es posible usar un valor predeterminado junto con importaciones con nombre en la misma declaración:

import MyDefaultExport, { MyClass, MyOtherClass} from "./MyClass";

Importar espacio de nombres

También es posible importar todo desde el archivo en un objeto:

import * as MyClasses from "./MyClass";
// use MyClasses.MyClass, MyClasses.MyOtherClass and MyClasses.default here

Notas

  • La sintaxis favorece las exportaciones predeterminadas como un poco más concisas porque su caso de uso es más común ( vea la discusión aquí ).
  • Una exportación predeterminada es en realidad una exportación con nombre con el nombre, defaultpor lo que puede importarla con una importación con nombre:

    import { default as MyDefaultExport } from "./MyFileWithADefaultExport";
David Sherret
fuente
24

export defaultafecta la sintaxis al importar la "cosa" exportada, al permitir importar, lo que se haya exportado, eligiendo el nombre en importsí mismo, sin importar cuál era el nombre cuando se exportó, simplemente porque está marcado como "predeterminado".

Un caso de uso útil, que me gusta (y uso), es permitir exportar una función anónima sin tener que nombrarla explícitamente , y solo cuando esa función se importa, se le debe dar un nombre:


Ejemplo:

Exportar 2 funciones, una es default:

export function divide( x ){
    return x / 2;
}

// only one 'default' function may be exported and the rest (above) must be named
export default function( x ){  // <---- declared as a default function
    return x * x;
}

Importar las funciones anteriores. Inventar un nombre para el defaultuno:

// The default function should be the first to import (and named whatever)
import square, {divide} from './module_1.js'; // I named the default "square" 

console.log( square(2), divide(2) ); // 4, 1

Cuando la {}sintaxis se usa para importar una función (o variable), significa que lo que se importa ya se nombró cuando se exportó, por lo que se debe importar exactamente con el mismo nombre, de lo contrario, la importación no funcionaría.


Ejemplos erróneos:

  1. La función predeterminada debe ser primero para importar

    import {divide}, square from './module_1.js
  2. divide_1no se exportó module_1.js, por lo que no se importará nada

    import {divide_1} from './module_1.js
  3. squareno se exportó module_1.js, porque {}le dice al motor que busque explícitamente solo exportaciones con nombre .

    import {square} from './module_1.js
vsync
fuente
No significa que exporta una sola cosa. Puede tener múltiples nombres y uno predeterminado en el mismo módulo. Predeterminado simplemente significa exactamente eso: es la exportación predeterminada si no especifica el nombre al importar, es decir, en import something fromlugar de import { somethingNamed } from.
Andris
También aprendí una nueva palabra en inglés aquí: "Erroneous" +1 para eso
Yuval Levy
12

Nota menor: Tenga en cuenta que cuando importa desde una exportación predeterminada, la denominación es completamente independiente. Esto realmente tiene un impacto en las refactorizaciones.

Digamos que tiene una clase Foocomo esta con una importación correspondiente:

export default class Foo { }

//the name 'Foo' could be anything, since it's just an
//identifier for the default export
import Foo from './Foo'

Ahora, si refactoriza su Fooclase Bary cambia el nombre del archivo, la mayoría de los IDE NO tocarán su importación. Entonces terminarás con esto:

export default class Bar { }

//the name 'Foo' could be anything, since it's just an
//identifier for the default export.
import Foo from './Bar'

Especialmente en Typecript, realmente aprecio las exportaciones con nombre y la refactorización más confiable. La diferencia es solo la falta de la defaultpalabra clave y las llaves. Este, por cierto, también le impide hacer un error tipográfico en su importación, ya que ahora tiene verificación de tipo.

export class Foo { }

//'Foo' needs to be the class name. The import will be refactored
//in case of a rename!
import { Foo } from './Foo'
Philipp Sumi
fuente
2
" 'Foo' debe ser el nombre de la clase " . - ¡no! Puede hacer lo import { Foo as Anything } from …mismo que import Anything from …con las exportaciones predeterminadas.
Bergi
Que puede cambiarle el nombre con un asrealmente no es el punto en ese comentario fuente. Gracias por el voto negativo; p
Philipp Sumi
1
No voté en contra, sin embargo, no estoy seguro de si ese argumento es convincente. No sé si me gustaría que mi IDE cambie el nombre de todas las importaciones al refactorizar un solo módulo, eso es exactamente de lo que se trata la modularización :-) Y parece ser más un "problema" IDE, no una razón para elegir el estilo de exportación ...
Bergi
Estoy de acuerdo en que utilizo exportaciones con nombre en aras del desarrollador UX aquí, pero entonces, podría argumentar que Typecript per se trata de eso. Refactorizo ​​con frecuencia, y dado que generalmente tengo una clase (en mi caso: React Component) por archivo, me gustaría que las importaciones sigan a un componente renombrado para no crear una desconexión. Por supuesto, esto puede o no tener sentido dependiendo del desarrollador individual.
Philipp Sumi
Encontré un artículo que dice lo mismo. Tal vez una posición razonable podría ser: deberíamos usar export defaultpara exportar el objeto principal de un proyecto, en particular desde un paquete npm (reemplaza a module.exports =). Pero, internamente en un proyecto, es mejor usar solo exportaciones con nombre.
Paleo
7

De la documentación :

Las exportaciones con nombre son útiles para exportar varios valores. Durante la importación, se podrá usar el mismo nombre para referirse al valor correspondiente.

En cuanto a la exportación predeterminada, solo hay una única exportación predeterminada por módulo. Una exportación predeterminada puede ser una función, una clase, un objeto o cualquier otra cosa. Este valor debe considerarse como el valor exportado "principal", ya que será el más sencillo de importar.

James Sumners
fuente
0

Cuando pones por defecto, se llama exportación por defecto. Solo puede tener una exportación predeterminada por archivo y puede importarla en otro archivo con el nombre que desee. Cuando no establece el valor predeterminado, se llama exportación con nombre, debe importarlo en otro archivo usando el mismo nombre con llaves dentro.

Abdullah Danyal
fuente
0

Tuve el problema de que el navegador no usa es6.

Lo solucioné con:

 <script type="module" src="index.js"></script>

El módulo de tipo le dice al navegador que use ES6.

export const bla = [1,2,3];

import {bla} from './example.js';

Entonces debería funcionar.

Marcel Zebrowski
fuente