💡 TL; DR;
Od razu chcesz poznać wyjaśnienie, a nie interesują Cie wyniki kompilacji? 👉👉👉 Wyjaśnienie.
Mamy dwa rodzaje exportów,
export foo; // named export
export default foo; // default export
które po kompilacji, wyglądają tak:
exports.foo = foo;
exports['default'] = foo;
Następnie mamy dwa rodzaje importów,
import {foo} from 'blah';
import foo from 'blah';
które po kompilacji, wyglądają tak:
var foo = require('blah').foo;
var foo = require('blah')['default'];
Dlaczego to działa tak, a nie inaczej ? Tutaj w końcu to zrozumiesz 🙂
Załóżmy, że mamy pustą klasę Human tak jak w kodzie poniżej. Klasa celowo jest pusta, skupiamy się na zrozumieniu importów i exportów, a implementacja klasy nie jest istotna (zamiast klasy moglibyśmy eksportować funkcję, obiekt czy cokolwiek innego-nie ważne).
// human.ts
export class Human{}
Zwróć proszę uwagę na formę export’u - to named export.
Na podstawie klasy human, którą eksportujemy poprzez “named export”, wyobraź sobie, że pod spodem tak naprawdę eksportowany jest obiekt z kluczem o nazwie Human. W kodzie wyglądałoby to tak:
// human.ts
export { Human: class {} }
Dlatego właśnie import tak zwanych, “named exports” wygląda tak:
import { Human } from './human.ts';
Tak naprawdę importujesz klucze obiektu o określonych z góry nazwach.
💡 Pamiętaj, że skoro importujesz obiekt o z góry określonych nazwach kluczy, to przy imporcie nazwy kluczy muszą się pokrywać. Możesz je natomiast zmapować na dowolną inną nazwę używając operatora `as`. Na przykład tak:
import { Human as SuperHuman } from './human.ts';
Właśnie zrozumiałeś named exports, to teraz zrozum default exports 👇
W przypadku kiedy mamy do czynienia z default export np.
export default class Human{}
// lub
class Human{};
// i 500 linijek później...
export default Human;
To pod spodem też exportowany jest obiekt, ale z kluczem default. Wygląda to mniej więcej tak:
export { default: Human };
Importować taki obiekt możemy w różny sposób, a najczęściej robimy to tak:
import Human from './human.ts'
// lub np.
import { default as Human } from './human.ts'
Zagadką jest, że skoro pod spodem exportowany jest obiekt o kluczu default, to skąd przy exporcie pisanym w ten sposób:
import Human from './human.ts'
Kompilator wie, że chodzi nam o to co kryje się pod kluczem default?
W trakcie takiego importu kompilator “w locie” wyciąga wartość, która jest zapisana pod kluczem default. Wygląda to mniej więcej tak:
export {default: Human}['default'];
Dzięki zapisowi [’default’]
tuż za eksportowanym obiektem, kompilator odnosi się od razu do klasy Human, która była przypisana pod kluczem default i zwraca bezpośrednio te klasę 🙂
Pozdrawiam i do zobaczenia w następnym poście!