`export const` vs.` export default` in ES6


204

Sto cercando di determinare se ci sono grandi differenze tra questi due, oltre a poter importare export defaultsemplicemente facendo:

import myItem from 'myItem';

E usando export constposso fare:

import { myItem } from 'myItem';

Mi chiedo se ci siano differenze e / o casi d'uso diversi da questo.


1
L'utilizzo constrenderà l'identificatore di sola lettura. Quindi, nel caso di valori primitivi, puoi considerarlo immutabile. Si noti che il valore stesso non è immutabile, quindi oggetti, matrici, ecc. Possono essere modificati, ma non riassegnati.
spmurrayzzz,

4
@spmurrayzzz: FWIW, anche i binding di importazione sono immutabili, proprio come const.
Felix Kling,

grazie per il chiarimento @FelixKling, non lo sapevo
spmurrayzzz

@FelixKling: almeno dall'esterno. Tuttavia potrebbero non essere costanti, le esportazioni possono essere modificate.
Bergi,

@Bergi: giusto, è per questo che ho detto collegamenti di importazione ;)
Felix Kling

Risposte:


327

È un'esportazione denominata rispetto a un'esportazione predefinita. export constè un'esportazione denominata che esporta una dichiarazione const o dichiarazioni.

Per sottolineare: ciò che conta qui è la exportparola chiave constutilizzata per dichiarare una dichiarazione const o dichiarazioni. exportpuò essere applicato anche ad altre dichiarazioni come dichiarazioni di classe o funzione.

Esportazione predefinita ( export default)

Puoi avere un'esportazione predefinita per file. Quando si importa è necessario specificare un nome e importare in questo modo:

import MyDefaultExport from "./MyFileWithADefaultExport";

Puoi dare questo nome a piacere.

Named Export ( export)

Con le esportazioni con nome, è possibile avere più esportazioni con nome per file. Quindi importare le esportazioni specifiche che si desidera racchiuse tra parentesi graffe:

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

Oppure è possibile utilizzare un valore predefinito insieme alle importazioni con nome nella stessa istruzione:

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

Importazione dello spazio dei nomi

È anche possibile importare tutto dal file su un oggetto:

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

Appunti

  • La sintassi favorisce le esportazioni predefinite come leggermente più concise perché il loro caso d'uso è più comune ( vedi la discussione qui ).
  • Un'esportazione predefinita è in realtà un'esportazione denominata con il nome, defaultquindi puoi importarla con un'importazione denominata:

    import { default as MyDefaultExport } from "./MyFileWithADefaultExport";

24

export defaultinfluenza la sintassi quando si importa la "cosa" esportata, quando si consente di importare, qualunque cosa sia stata esportata, scegliendo il nome in importsé, indipendentemente dal nome quando è stato esportato, semplicemente perché è contrassegnato come "predefinito".

Un utile caso d'uso, che mi piace (e utilizzo), è consentire di esportare una funzione anonima senza dover esplicitamente nominarla e solo quando tale funzione viene importata, deve essere assegnato un nome:


Esempio:

Esporta 2 funzioni, una è 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;
}

Importa le funzioni sopra. Inventando un nome per defaultquello:

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

Quando la {}sintassi è usato per importare una funzione (o variabile), ciò significa che tutto ciò che viene importato è stato già nominato in caso di esportazione, per cui bisogna importarlo dal esattamente lo stesso nome, altrimenti l'importazione non avrebbe funzionato.


Esempi errati:

  1. La funzione predefinita deve essere la prima da importare

    import {divide}, square from './module_1.js
  2. divide_1non è stato esportato in module_1.js, quindi nulla verrà importato

    import {divide_1} from './module_1.js
  3. squarenon è stato esportato in module_1.js, perché {}indica al motore di cercare esplicitamente solo le esportazioni con nome .

    import {square} from './module_1.js

Ciò non significa che esporti una sola cosa. Puoi avere più nomi e uno predefinito nello stesso modulo. Predefinito significa esattamente questo: è l'esportazione predefinita se non si specifica il nome durante l'importazione, ovvero import something frominvece di import { somethingNamed } from.
Andris,

Ho anche imparato una nuova parola inglese qui: "Erroneous" +1 per questo
Yuval Levy

12

Nota minore: tenere presente che quando si importa da un'esportazione predefinita, la denominazione è completamente indipendente. Questo in realtà ha un impatto sui refactoring.

Supponiamo che tu abbia una classe Foocome questa con un'importazione corrispondente:

export default class Foo { }

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

Ora, se si esegue il refactoring della propria Fooclasse Bare si rinomina anche il file, la maggior parte degli IDE NON tocca l'importazione. Quindi finirai con questo:

export default class Bar { }

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

Soprattutto in Typescript, apprezzo molto le esportazioni nominate e il refactoring più affidabile. La differenza è solo la mancanza della defaultparola chiave e delle parentesi graffe. Questo BTW ti impedisce anche di fare un refuso nella tua importazione dato che ora hai il controllo del 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'

2
" 'Foo' deve essere il nome della classe. " - no! Puoi fare altrettanto facilmente import { Foo as Anything } from …come puoi fare import Anything from …con le esportazioni predefinite.
Bergi,

Che tu possa rinominarlo con un non asè davvero il punto in quel commento sorgente. Grazie per il downvote; p
Philipp Sumi il

1
Non ho espresso il mio voto negativo, tuttavia non sono sicuro che tale argomento sia convincente. Non so se vorrei che il mio IDE rinominasse tutte le importazioni durante il refactoring di un singolo modulo, questo è esattamente ciò che riguarda la modularizzazione :-) E sembra essere più un "problema" IDE non un motivo per scegliere lo stile di esportazione ...
Bergi,

Sono d'accordo sul fatto che uso qui le esportazioni denominate per il bene dello sviluppatore UX - ma poi, potresti sostenere che Typescript in sé è tutto. Rifletto spesso e, dato che di solito ho una classe (nel mio caso: React Component) per file, vorrei assolutamente che le importazioni seguissero un componente rinominato per non creare una disconnessione. Naturalmente, ciò può o non ha senso a seconda del singolo sviluppatore.
Philipp Sumi,

Ho trovato un articolo che dice la stessa cosa. Forse una posizione ragionevole potrebbe essere: dovremmo usare export defaultper esportare l'oggetto principale di un progetto, in particolare da pacchetti npm (sostituisce a module.exports =). Ma, internamente in un progetto, è meglio usare solo esportazioni denominate.
Paleo,

7

Dalla documentazione :

Le esportazioni con nome sono utili per esportare diversi valori. Durante l'importazione, si sarà in grado di utilizzare lo stesso nome per fare riferimento al valore corrispondente.

Per quanto riguarda l'esportazione predefinita, esiste una sola esportazione predefinita per modulo. Un'esportazione predefinita può essere una funzione, una classe, un oggetto o qualsiasi altra cosa. Questo valore deve essere considerato come il valore esportato "principale" poiché sarà il più semplice da importare.


0

Quando si mette il valore predefinito, si chiama esportazione predefinita. Puoi avere solo un'esportazione predefinita per file e puoi importarlo in un altro file con il nome che desideri. Quando non metti il ​​valore predefinito, si chiama export, devi importarlo in un altro file usando lo stesso nome con parentesi graffe al suo interno.


0

Ho avuto il problema che il browser non utilizza es6.

L'ho risolto con:

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

Il modulo del tipo dice al browser di usare ES6.

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

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

Quindi dovrebbe funzionare.

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.