Skip to content

Archives

  • styczeń 2022
  • grudzień 2021
  • listopad 2021
  • październik 2021
  • wrzesień 2021

Categories

  • Brak kategorii
Trend RepositoryArticles and guides
Articles

Wyczerpujący przewodnik po „Module System” w TypeScript (z przykładami)

On 16 października, 2021 by admin
  • Standard modułów
  • Eksporty nazwane
  • Default Export
  • Import And Export Alias
  • Importuj wszystkie nazwane eksporty
  • Re-eksporty
  • Import dla efektu ubocznego

Standard modułów

EcmaScript ustandaryzował jak powinniśmy importować moduły w JavaScript i standard ten obraca się wokół dwóch słów kluczowych, import i export. Ponieważ system modułów w JavaScript staje się coraz bardziej popularny, co roku pojawiają się nowe zmiany w tym standardzie.

W tym poradniku przyjrzymy się semantyce systemu modułów w TypeScript (który w większości przypomina standard EcmaScript) oraz temu, jak działają słowa kluczowe import i export.

Eksporty nazwane

Słowo kluczowe export sprawia, że wartość (zmienna) zdefiniowana w pliku jest dostępna do importu w innych plikach modułów. Kiedy moduł jest importowany w innym pliku modułu przy użyciu słowa kluczowego import, plik importujący może określić wartości, do których chce mieć dostęp z importowanego modułu.

// program.ts 
import { A } from 'path/to/values';console.log( A ); // "Apple"

W powyższym przykładzie importujemy values.ts w pliku program.ts i wyodrębniamy A wyeksportowanego członka. Oznacza to, że values.ts musi wyeksportować wartość A w jakiejś formie. Istnieje wiele sposobów ekspozycji A.

// values.ts
var A = "Apple"; // can also use `let` or `const`
class B {}
function C(){}
enum D{}export { A, B, C, D };

Możesz wyeksportować dowolną dostępną wartość TypeScript z poprawnym identyfikatorem (nazwą). W tym przykładzie eksportujemy zmienną A (może to być również stała), klasę B , i tak dalej. Używając składni export {}, możesz wyeksportować tyle wartości, ile chcesz i każdy może je zaimportować używając składni import { A, B }. Nie musisz importować wszystkich wyeksportowanych wartości.

Istnieje inny sposób na wyeksportowanie wartości tam, gdzie została zadeklarowana.

// values.ts
export const A = { name: "Apple" };
export class B {}
export function C(){}
export enum D{}

W powyższym przykładzie wyeksportowaliśmy wszystkie wartości tam, gdzie zostały zadeklarowane. Nie musisz również inicjalizować wartości, możesz to zrobić później w dół pliku. Jest to znacznie przyjemniejszy sposób w porównaniu do poprzedniego.

W obu przypadkach wszyscy twoi członkowie eksportu są dostępni w tym samym pliku, jeśli potrzebujesz ich użyć. Posiadanie słowa kluczowego export na wartości nie zmienia jej zachowania wewnątrz pliku modułu.

Default Export

Do tej pory eksportowaliśmy wartości, które mogą być importowane tylko przez podanie nazwy członków eksportu, takich jak import { A } from 'path/to/values', gdzie A jest członkiem eksportu values.ts. Są to tak zwane eksporty nazwane.

Dozwolone jest również wyeksportowanie pojedynczej wartości, która może być importowana bez podawania nazwy. Ta wartość powinna być określona słowem kluczowym default wraz ze słowem kluczowym export.

// values.ts
var A = "Apple"; // can also use `let` or `const`
class A {}
function A(){}
enum A{}export default A;

Jedynie pojedyncza wartość jest dozwolona do wyeksportowania jako domyślny eksport, stąd nie masz wyrażenia export default {...} do pracy. W przeciwieństwie do nazwanych eksportów, wartość nie może być wyeksportowana jako domyślna z deklaracją zmiennej (lub stałej) z wyjątkiem deklaracji function i class.

// values.ts
export default var A = "Apple"; // ❌ invalid syntax
export default enum D{} // ❌ illegal: not a function or class
export default class B {} // ✅ legal
export default function C(){} // ✅ legal

Jednakże możesz wyeksportować wartość bezpośrednio jako domyślny eksport. Oznacza to, że każde wyrażenie JavaScript może zostać wyeksportowane jako domyślna wartość eksportu.

// values.ts
export default "Hello"; // string
export default {}; // object
export default () => undefined; // function
export default function(){}; // function
export default class{}; // class

Ponieważ domyślny eksport nie posiada nazwy eksportu, możemy nadać mu dowolną nazwę podczas importu. Możesz mieć nazwane eksporty i domyślny eksport w tym samym pliku modułu. Podobnie, możesz zaimportować wartości domyślnego eksportu i nazwanego eksportu w pojedynczej deklaracji import, jak pokazano poniżej.

import Apple, { B, C } from 'path/to/values';

W powyższym przykładzie, Apple jest nazwą, której użyliśmy do pobrania domyślnego eksportu z values.ts. Możesz opuścić wyrażenie { B, C } lub nazwę Apple z deklaracji import, jeśli nie zamierzasz jej używać.

💡 Podobnie jak w przypadku nazwanych eksportów, nie jest obowiązkowe importowanie domyślnej wartości eksportu, gdy używana jest deklaracja import. Ale, Apple musi znajdować się przed nazwanymi eksportami w podpisie deklaracji import.

Możesz również użyć składni as default w podpisie export {}, aby wyeksportować wartość jako domyślną wraz z innymi nazwanymi eksportami. Nazywa się to aliasing i jest wyjaśnione w następnej sekcji.

// values.ts
var A = "Apple"; // can also use `let` or `const`
class B {}
function C(){}
enum D{}export { A as default, B, C, D };

💡 Powód, dla którego nie używam i nie polecam default eksportu ma związek z doświadczeniem deweloperskim. Jak się dowiedzieliśmy, możesz podać dowolną nazwę dla domyślnego memebera eksportu modułu w deklaracji import. Jeśli ta wartość jest importowana w wielu plikach, możesz odwołać się do niej z dowolną wybraną przez siebie nazwą, a posiadanie różnych nazw dla tego samego członka eksportu tego samego modułu jest złym DX.

Import And Export Alias

W przypadku domyślnego eksportu, możesz odwołać się do wartości z dowolną wybraną przez siebie nazwą w deklaracji import. Jednak nie jest tak w przypadku eksportów nazwanych. Można jednak użyć słowa kluczowego as, aby odwołać się do nazwanej wartości eksportu z wybraną przez siebie nazwą.

// program.ts
import A, { B as Ball } from 'path/to/values';console.log( B ); // ❌ Error: Cannot find name 'B'.
console.log( Ball ); // ✅ legal

W powyższym przykładzie importujemy B z values.ts, ale zmieniono jego nazwę na Ball. W związku z tym w pliku program.ts użyjemy Apple zamiast B. Kiedy aliasujesz członka eksportu, oryginalna nazwa nie istnieje już w zakresie globalnym, stąd B nie będzie już istnieć w pliku program.ts.

💡 Nie możesz aliasować domyślnego członka eksportu, ponieważ możesz już podać dowolną nazwę, ale możesz użyć import { default as defaultValue, }.

Dozwolone jest również aliasowanie wartości podczas eksportowania przy użyciu as słowa kluczowego.

// values.ts
var A = "Apple"; // can also use `let` or `const`
class B {}
function C(){}
enum D{}export { A as default, B, C as Cat, D };

W powyższym przykładzie wyeksportowaliśmy zmienną A jako domyślny eksport i funkcję C jako Cat. Dlatego każdy, kto importuje te wartości z pliku values.ts, musi użyć domyślnej składni importu dla A i Cat dla wartości C.

Importuj wszystkie nazwane eksporty

Możesz zaimportować wszystkie nazwane eksporty z pliku za pomocą składni * as.

// program.ts
import Apple, * as values from 'path/to/values';console.log( values.B );
console.log( values.C );
console.log( values.D );

Tutaj, wszystkie nazwane eksporty z values.ts zostaną zapisane pod values, który będzie obiektem, gdzie keys będzie nazwą członków eksportu, a values będzie wyeksportowanymi wartościami członków eksportu.

Re-eksporty

Zaimportowana wartość może zostać ponownie wyeksportowana w normalny sposób. Kiedy coś importujesz, masz odniesienie do wartości importu i możesz użyć tej samej wartości w składni export. Nic nie jest w tym złego.

// lib.ts
import A, { B, C as Cat, D } from 'path/to/values';export { D as default, A, B, Cat as C, D };

W powyższym przykładzie zaimportowałeś kilka wartości z values.ts wewnątrz lib.ts i wyeksportowałeś zgodnie z własnymi preferencjami. Jest to świetne, jeśli chcesz użyć tego importu w lib.ts, jak również wyeksportować niektóre z nich, jeśli inny plik potrzebuje ich, gdy importuje z lib.ts.

Jednakże mamy również export ... from oświadczenie, aby wyeksportować wartości z pliku bez konieczności importowania ich najpierw. Jest to świetne rozwiązanie, gdy chcesz zachować jeden punkt wejścia dla wszystkich importów w twoim module.

// lib.ts// re-exports
export { P as Paper, Q } from 'path/to/values-1';
export { N, O as Orange } from 'path/to/other/values-2';// default export
export default "hello";class B {}
function C(){}// named exports
export { B, C as Cat };

W powyższym przykładzie eksportujemy niektórych członków eksportu values-1.ts i values-2.ts z pliku lib.ts (z wyjątkiem domyślnego eksportu). Możemy również użyć aliasingu w składni export ... from.

Składnia re-eksportu nie wpływa na bieżący plik, stąd możesz mieć swoje zwykłe eksporty w pliku, jak pokazano powyżej. W przeciwieństwie do słowa kluczowego export, składnia export ... from nie pozwala na dostęp do ponownie wyeksportowanych członków. Stąd nie będziesz mógł uzyskać dostępu do P lub Orange w pliku lib.ts.

// lib.ts
export { P as Paper, Q } from 'path/to/values-1';
export { N, O as Orange } from 'path/to/other/values-2';console.log( P ); // ❌ Error: Cannot find name 'P'.
console.log( Orange ); // ❌ Error: Cannot find name 'Orange'.

Możesz wyeksportować wszystkie nazwane eksporty z pliku przy użyciu składni export * from, tak jak masz możliwość zmiany ich nazw podczas eksportowania przy użyciu export * as ... from.

// lib.ts
export * from 'path/to/values-1';
export * as values2 from 'path/to/other/values-2';

Z powyższego przykładu, jeśli values-1.ts eksportuje P i Q, to każdy może zaimportować P i Q z lib.ts. Jednak wszystkie nazwane eksporty values-2.ts są reeksportowane jako values2 nazwany eksport lib.ts, dlatego musisz zaimportować je za pomocą następującej składni.

// program.ts
import { P, Q, values2 } from 'path/to/lib';

Nie można uzyskać dostępu do domyślnego eksportu za pomocą składni export ... from w normalny sposób. Ale można wyeksportować domyślny eksport przy użyciu słowa kluczowego default.

// lib.ts
export { default } from 'path/to/values-1';
export { default as Apple } from 'path/to/values-2';

W powyższym przykładzie domyślny eksport lib.ts jest domyślną wartością eksportu values-2.ts. Domyślna wartość eksportu values-2 zostanie wyeksportowana z lib.ts jako Apple o nazwie export.

Import dla efektu ubocznego

Czy można sobie wyobrazić importowanie pliku bez określania wyeksportowanych członków?

import 'path/to/action';

W powyższym przykładzie importujemy action.ts, ale określiliśmy dowolnych członków eksportowanych przez action.ts. Jest to poprawna składnia, ale jest używana do uzyskania zupełnie innego wyniku.

Gdy importujesz plik używając słowa kluczowego import, jest ono najpierw wykonywane, a następnie wszyscy członkowie eksportu są dostępni do importu. Stąd w poniższym przykładzie plik importujący PI otrzymałby 3.14 jako floating-point number.

export const PI = parseFloat( "3.14" ); // 3.14

Podążając za tą samą logiką, jeśli chcesz utworzyć efekt uboczny przez importowanie pliku, to możesz to całkowicie zrobić. Tak więc na przykład, jeśli istnieje plik, który inicjalizuje niektóre zmienne globalne, możesz go zaimportować bez określania wyeksportowanych członków tego pliku (mógłby on również nie eksportować żadnego z nich).

Kompilator TypeScript może utworzyć plik JavaScript bundle (.js) przez kompilację dwóch lub więcej plików .ts razem. Zwykle odbywa się to poprzez dostarczenie wejściowego pliku TypeScript, a następnie przejście przez jego drzewo zależności.

Drzewo zależności jest konstruowane przez spojrzenie na wszystkie import deklaracje (zależności) pliku wejściowego i śledzenie zależności tych importowanych plików. Jeśli chcesz dołączyć plik, którego kod może tworzyć pewne efekty uboczne w czasie wykonywania, to powinieneś zaimportować ten plik bez określania eksportowanych członków w składni import. Można to zrobić w pliku wejściowym lub wewnątrz dowolnego pliku, który znajduje się wewnątrz drzewa zależności.

Dodaj komentarz Anuluj pisanie odpowiedzi

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *

Archiwa

  • styczeń 2022
  • grudzień 2021
  • listopad 2021
  • październik 2021
  • wrzesień 2021

Meta

  • Zaloguj się
  • Kanał wpisów
  • Kanał komentarzy
  • WordPress.org
  • DeutschDeutsch
  • NederlandsNederlands
  • SvenskaSvenska
  • DanskDansk
  • EspañolEspañol
  • FrançaisFrançais
  • PortuguêsPortuguês
  • ItalianoItaliano
  • RomânăRomână
  • PolskiPolski
  • ČeštinaČeština
  • MagyarMagyar
  • SuomiSuomi
  • 日本語日本語

Copyright Trend Repository 2022 | Theme by ThemeinProgress | Proudly powered by WordPress