`export const` vs.` export default` w ES6

204

Próbuję ustalić, czy istnieją między nimi duże różnice, poza tym, że mogę je importować, export defaultwykonując po prostu:

import myItem from 'myItem';

I używając export constmogę zrobić:

import { myItem } from 'myItem';

Zastanawiam się, czy istnieją jakieś różnice i / lub przypadki użycia inne niż to.

ajmajmajma
źródło
1
Użycie constspowoduje, że identyfikator będzie tylko do odczytu. Tak więc w przypadku pierwotnych wartości można uznać to za niezmienne. Zauważ, że sama wartość nie jest niezmienna, więc obiekty, tablice itp. Można zmienić - tylko nie przypisać ponownie.
spmurrayzzz
4
@spmurrayzzz: FWIW, powiązania importu są również niezmienne, podobnie jak const.
Felix Kling,
dzięki za wyjaśnienie @FelixKling, nie wiedziałem o tym
spmurrayzzz
@FelixKling: Przynajmniej z zewnątrz. Mogą nie być stałe, eksport można zmienić.
Bergi,
@Bergi: tak, dlatego powiedziałem importowanie powiązań ;)
Felix Kling

Odpowiedzi:

326

Jest to eksport nazwany a domyślny eksport. export constto nazwany eksport, który eksportuje stałą deklarację lub deklaracje.

Aby podkreślić: ważne jest tutaj exportsłowo kluczowe constużywane do deklarowania stałej deklaracji lub deklaracji. exportmogą być również stosowane do innych deklaracji, takich jak deklaracje klas lub funkcji.

Domyślny eksport ( export default)

Możesz mieć jeden domyślny eksport na plik. Podczas importowania musisz podać nazwę i zaimportować w następujący sposób:

import MyDefaultExport from "./MyFileWithADefaultExport";

Możesz nadać temu dowolne imię.

Nazwany eksport ( export)

Dzięki nazwanym eksportom możesz mieć wiele nazwanych eksportów na plik. Następnie zaimportuj określony eksport w nawiasach klamrowych:

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

Lub można użyć wartości domyślnej wraz z nazwanymi importami w tym samym zestawieniu:

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

Import przestrzeni nazw

Możliwe jest również zaimportowanie wszystkiego z pliku na obiekt:

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

Notatki

  • Składnia preferuje domyślny eksport jako nieco bardziej zwięzły, ponieważ ich przypadek użycia jest częstszy ( zobacz dyskusję tutaj ).
  • Domyślny eksport to tak zwany eksport o nazwie, defaultdzięki czemu można go zaimportować za pomocą importu o nazwie:

    import { default as MyDefaultExport } from "./MyFileWithADefaultExport";
David Sherret
źródło
24

export defaultwpływa na składnię podczas importowania eksportowanej „rzeczy”, podczas zezwalania na importowanie wszystkiego, co zostało wyeksportowane, poprzez wybranie samej nazwy import, bez względu na to, jaka była nazwa podczas eksportowania, po prostu dlatego, że jest oznaczona jako „domyślna”.

Przydatnym przypadkiem użycia, który lubię (i używam), jest możliwość wyeksportowania anonimowej funkcji bez wyraźnego nadawania jej nazwy, a tylko po zaimportowaniu tej funkcji należy nadać jej nazwę:


Przykład:

Eksportuj 2 funkcje, jedna to 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;
}

Zaimportuj powyższe funkcje. Wymyślając nazwę dla tego default:

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

Kiedy {}składnia jest używana do importowania funkcji (lub zmiennej), oznacza to, że wszystko, co jest importowane, było już nazwane podczas eksportowania, więc należy zaimportować je pod dokładnie taką samą nazwą, w przeciwnym razie import nie zadziała.


Błędne przykłady:

  1. Domyślna funkcja musi być najpierw importowana

    import {divide}, square from './module_1.js
  2. divide_1nie został wyeksportowany module_1.js, więc nic nie zostanie zaimportowane

    import {divide_1} from './module_1.js
  3. squarenie został wyeksportowany module_1.js, ponieważ {}nakazuje silnikowi jawne wyszukiwanie tylko nazwanych eksportów.

    import {square} from './module_1.js
vsync
źródło
To nie znaczy, że eksportuje jedną rzecz. Możesz mieć wiele nazwanych i jeden domyślny w tym samym module. Domyślne oznacza po prostu dokładnie to - to domyślny eksport, jeśli nie podasz nazwy podczas importowania, czyli import something fromzamiast import { somethingNamed } from.
Andris
Nauczyłem się również nowego angielskiego słowa: „Błędne” +1 za to
Yuval Levy
12

Drobna uwaga: pamiętaj, że podczas importowania z domyślnego eksportu nazewnictwo jest całkowicie niezależne. Ma to faktycznie wpływ na refaktoryzację.

Załóżmy, że masz taką klasę Fooz odpowiednim importem:

export default class Foo { }

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

Teraz, jeśli zmienisz Fooklasę na swoją, Bara także zmienisz nazwę pliku, większość IDE NIE dotknie twojego importu. Skończysz z tym:

export default class Bar { }

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

Szczególnie w maszynopisie naprawdę doceniam nazwany eksport i bardziej niezawodne refaktoryzowanie. Różnica polega tylko na braku defaultsłowa kluczowego i nawiasów klamrowych. To również zapobiega tworzeniu literówki w imporcie, ponieważ teraz masz sprawdzanie typów.

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
źródło
2
Foo” musi być nazwą klasy. ”- nie! Możesz zrobić to tak łatwo, import { Foo as Anything } from …jak to możliwe import Anything from …przy domyślnych eksportach.
Bergi,
To, że możesz zmienić jego nazwę za pomocą an, astak naprawdę nie jest celem tego komentarza źródłowego. Dzięki za przegłosowanie; p
Philipp Sumi,
1
Nie głosowałem za tym, ale nie jestem pewien, czy ten argument jest przekonujący. Nie wiem, czy chciałbym, aby moje IDE zmieniło nazwę wszystkich importów podczas refaktoryzacji pojedynczego modułu, właśnie o to chodzi w modularyzacji :-) I wydaje się, że to raczej „problem” IDE, a nie powód, aby wybrać styl eksportu …
Bergi,
Zgadzam się, że używam nazwanych eksportów ze względu na UX dla programistów - ale możesz argumentować, że o to chodzi w maszynie do pisania. Często refaktoryzuję i biorąc pod uwagę, że zazwyczaj mam jedną klasę (w moim przypadku: React Component) na plik, absolutnie chciałbym, aby import podążał za zmienioną nazwą komponentu, aby nie tworzyć rozłączenia. Oczywiście może to, ale nie musi mieć sensu, w zależności od indywidualnego dewelopera.
Philipp Sumi,
Znalazłem artykuł, który mówi to samo. Być może rozsądną pozycją może być: powinniśmy użyć export defaultdo eksportu głównego obiektu projektu, w szczególności z pakietów npm (zastępuje a module.exports =). Ale wewnętrznie w projekcie lepiej jest używać tylko nazwanego eksportu.
Paleo
7

Z dokumentacji :

Nazwane eksporty są przydatne do eksportowania kilku wartości. Podczas importu będzie można użyć tej samej nazwy w celu odniesienia do odpowiedniej wartości.

W przypadku domyślnego eksportu istnieje tylko jeden domyślny eksport na moduł. Domyślnym eksportem może być funkcja, klasa, obiekt lub cokolwiek innego. Wartość tę należy traktować jako „główną” wartość eksportu, ponieważ będzie ona najłatwiejsza do zaimportowania.

James Sumners
źródło
0

Po ustawieniu domyślnym nazywany jest domyślnym eksportem. Możesz mieć tylko jeden domyślny eksport na plik i możesz go zaimportować do innego pliku o dowolnej nazwie. Jeśli nie ustawisz wartości domyślnej, nazywanej eksportem, musisz zaimportować ją do innego pliku, używając tej samej nazwy z nawiasami klamrowymi w środku.

Abdullah Danyal
źródło
0

Miałem problem, że przeglądarka nie używa ES6.

Naprawiłem to za pomocą:

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

Moduł typu mówi przeglądarce, aby używała ES6.

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

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

To powinno działać.

Marcel Zebrowski
źródło