W poprzednich ćwiczeniach poznaliśmy dwa główne systemy modułów w JavaScript: ES Modules oraz CommonJS. Oba systemy umożliwiają organizację kodu w niezależne moduły, ale zapoznaliśmy się głównie ze statycznymi importami. Teraz przejdziemy do następnego poziomu - dynamicznego importowania modułów, które daje nam znacznie większą elastyczność.
Dla naszego systemu zarządzania Parkiem Jurajskim, dynamiczne importy mogą być kluczowe. Wyobraź sobie, że potrzebujemy różnych procedur awaryjnych w zależności od tego, co się dzieje - ucieczka T-Rexa wymaga innego zestawu akcji niż awaria zasilania czy zbliżający się huragan!
Dynamiczne importowanie modułów pozwala na ładowanie modułów w trakcie działania programu, a nie podczas jego inicjalizacji. Oznacza to, że możemy wczytać moduł dokładnie wtedy, gdy jest potrzebny, oszczędzając pamięć i czas ładowania dla modułów, które mogą nigdy nie zostać użyte.
Dynamiczny import używa funkcji
import(), która zwraca Promise zawierające załadowany moduł:1// Statyczny import (zawsze ładowany)
2import { DinosaurTracker } from './dinosaurTracker.js';
3
4// Dynamiczny import (ładowany na żądanie)
5import('./emergencyProcedures.js')
6 .then(module => {
7 // Teraz możemy użyć załadowanego modułu
8 module.initializeEmergencyProtocol();
9 })
10 .catch(error => {
11 console.error('Nie udało się załadować procedur awaryjnych:', error);
12 });Jeszcze wygodniej jest używać dynamicznego importu z async/await:
1async function handleEmergency(type) {
2 try {
3 // Dynamicznie importujemy odpowiedni moduł procedury awaryjnej
4 const emergencyModule = await import(`./emergencies/${type}.js`);
5
6 // Używamy załadowanego modułu
7 return emergencyModule.executeProtocol();
8 } catch (error) {
9 console.error(`Nie udało się załadować procedury: ${type}`, error);
10 // Fallback do ogólnej procedury awaryjnej
11 const fallbackModule = await import('./emergencies/general.js');
12 return fallbackModule.executeProtocol();
13 }
14}
15
16// Użycie naszej funkcji
17handleEmergency('dinosaurEscape').then(result => {
18 console.log('Status procedury awaryjnej:', result);
19});Zastanówmy się nad praktycznymi zastosowaniami dynamicznego importowania w naszym systemie zarządzania Parkiem Jurajskim:
Możemy ładować funkcjonalności tylko wtedy, gdy są potrzebne, co jest szczególnie przydatne dla rzadko używanych, ale dużych modułów:
1// dashboardController.js
2async function loadDashboard(dashboardType) {
3 // Bazowy dashboard zawsze załadowany
4 const statusPanel = document.getElementById('statusPanel');
5 statusPanel.innerHTML = 'Ładowanie...';
6
7 try {
8 // Dynamicznie importujemy żądany typ dashboardu
9 const dashboardModule = await import(`./dashboards/${dashboardType}Dashboard.js`);
10
11 // Inicjalizujemy dashboard
12 const dashboard = new dashboardModule.default();
13 await dashboard.initialize(statusPanel);
14
15 console.log(`Dashboard ${dashboardType} załadowany pomyślnie`);
16 } catch (error) {
17 console.error(`Błąd ładowania dashboardu ${dashboardType}: `, error);
18 statusPanel.innerHTML = `Błąd ładowania dashboardu: ${error.message}`;
19 }
20}
21
22// Przyciski w interfejsie użytkownika
23document.getElementById('btnDinosaurs').addEventListener('click', () => {
24 loadDashboard('dinosaurs');
25});
26
27document.getElementById('btnSecurity').addEventListener('click', () => {
28 loadDashboard('security');
29});
30
31document.getElementById('btnVisitors').addEventListener('click', () => {
32 loadDashboard('visitors');
33});Możemy dynamicznie ładować różne implementacje w zależności od środowiska (produkcja, rozwój, testowe):
1async function initializeTracking() {
2 const environment = process.env.NODE_ENV || 'development';
3
4 try {
5 // Ładujemy odpowiednią implementację dla danego środowiska
6 const trackingModule = await import(`./tracking/${environment}.js`);
7
8 // Inicjalizujemy system śledzenia
9 const tracker = trackingModule.createTracker();
10 tracker.initialize();
11
12 return tracker;
13 } catch (error) {
14 console.error(`Nie udało się zainicjalizować śledzenia dla środowiska ${environment}: `, error);
15 // Fallback do wersji dla developmentu
16 const fallbackModule = await import('./tracking/development.js');
17 return fallbackModule.createTracker();
18 }
19}
20
21// Użycie funkcji
22initializeTracking().then(tracker => {
23 tracker.trackEvent('app_initialized', { timestamp: Date.now() });
24});W aplikacji frontendowej możemy opóźnić ładowanie komponentów interfejsu, aby przyspieszyć początkowe ładowanie strony:
1// dynamicComponents.js
2export async function loadComponent(componentName) {
3 try {
4 const module = await import(`./components/${componentName}.js`);
5 return module.default;
6 } catch (error) {
7 console.error(`Nie udało się załadować komponentu ${componentName}: `, error);
8 throw error;
9 }
10}
11
12// W głównym pliku aplikacji
13import { loadComponent } from './dynamicComponents.js';
14
15document.getElementById('btnShowMap').addEventListener('click', async () => {
16 try {
17 // Ładujemy mapę parku tylko, gdy użytkownik jej potrzebuje
18 const ParkMap = await loadComponent('ParkMap');
19 const mapContainer = document.getElementById('mapContainer');
20
21 const parkMap = new ParkMap({
22 container: mapContainer,
23 initialZoom: 2,
24 centerCoordinates: [34.5, 12.8]
25 });
26
27 parkMap.render();
28 } catch (error) {
29 alert(`Nie udało się załadować mapy: ${error.message}`);
30 }
31});Jednym z najważniejszych zastosowań w naszym parku będzie system procedur bezpieczeństwa:
1// securitySystem.js
2export class SecuritySystem {
3 constructor() {
4 this.activeProtocols = new Map();
5 this.alertLevel = 'green';
6 }
7
8 async activateProtocol(protocolName, params = {}) {
9 try {
10 // Sprawdzamy, czy protokół jest już aktywny
11 if (this.activeProtocols.has(protocolName)) {
12 console.log(`Protokół ${protocolName} jest już aktywny`);
13 return this.activeProtocols.get(protocolName);
14 }
15
16 // Dynamicznie importujemy protokół
17 const protocolModule = await import(`./protocols/${protocolName}.js`);
18
19 // Inicjalizujemy protokół
20 const protocol = new protocolModule.default(params);
21 await protocol.initialize();
22
23 // Dodajemy do aktywnych protokołów
24 this.activeProtocols.set(protocolName, protocol);
25
26 console.log(`Protokół ${protocolName} aktywowany pomyślnie`);
27 return protocol;
28 } catch (error) {
29 console.error(`Błąd aktywacji protokołu ${protocolName}: `, error);
30 throw new Error(`Nie udało się aktywować protokołu ${protocolName}: ${error.message}`);
31 }
32 }
33
34 async deactivateProtocol(protocolName) {
35 const protocol = this.activeProtocols.get(protocolName);
36 if (!protocol) {
37 console.log(`Protokół ${protocolName} nie jest aktywny`);
38 return false;
39 }
40
41 try {
42 await protocol.shutdown();
43 this.activeProtocols.delete(protocolName);
44 console.log(`Protokół ${protocolName} dezaktywowany pomyślnie`);
45 return true;
46 } catch (error) {
47 console.error(`Błąd dezaktywacji protokołu ${protocolName}: `, error);
48 return false;
49 }
50 }
51
52 async handleEmergency(type, location) {
53 console.log(`Obsługa sytuacji awaryjnej: ${type} w lokalizacji ${location}`);
54
55 // Aktualizujemy poziom alertu
56 this.alertLevel = 'red';
57
58 try {
59 // Importujemy odpowiednią procedurę awaryjną
60 const emergencyModule = await import(`./emergencies/${type}.js`);
61
62 // Uruchamiamy procedurę
63 const procedure = new emergencyModule.EmergencyProcedure(location);
64 const emergencyId = await procedure.execute();
65
66 console.log(`Procedura awaryjna dla ${type} uruchomiona, ID: ${emergencyId}`);
67 return emergencyId;
68 } catch (error) {
69 console.error(`Nie udało się obsłużyć sytuacji awaryjnej ${type}: `, error);
70
71 // Fallback do ogólnej procedury awaryjnej
72 try {
73 const generalModule = await import('./emergencies/general.js');
74 const procedure = new generalModule.EmergencyProcedure(location, { originalType: type });
75 return procedure.execute();
76 } catch (fallbackError) {
77 console.error(`Krytyczny błąd! Nawet ogólna procedura nie działa: `, fallbackError);
78 return null;
79 }
80 }
81 }
82}
83
84// Użycie systemu bezpieczeństwa
85const security = new SecuritySystem();
86
87// Przykłady aktywacji protokołów
88document.getElementById('btnLockdown').addEventListener('click', async () => {
89 try {
90 const protocol = await security.activateProtocol('lockdown', {
91 sectors: ['A1', 'B2'],
92 reason: 'Ucieczka dinozaura'
93 });
94
95 document.getElementById('status').textContent = `Protokół blokady aktywny w ${protocol.affectedSectors.length} sektorach`;
96 } catch (error) {
97 alert(`Błąd aktywacji protokołu: ${error.message}`);
98 }
99});
100
101// Przykład obsługi sytuacji awaryjnej
102async function reportEmergency(type, location) {
103 try {
104 const emergencyId = await security.handleEmergency(type, location);
105 return emergencyId;
106 } catch (error) {
107 console.error(`Nie udało się zgłosić sytuacji awaryjnej: `, error);
108 return null;
109 }
110}Zobaczmy, jak mogą wyglądać niektóre z modułów, które dynamicznie importujemy w naszym systemie:
1// protocols/lockdown.js
2export default class LockdownProtocol {
3 constructor(params) {
4 this.sectors = params.sectors || [];
5 this.reason = params.reason || 'Nieznany powód';
6 this.timestamp = new Date();
7 this.active = false;
8 this.affectedSectors = [];
9 }
10
11 async initialize() {
12 console.log(`Inicjalizacja protokołu blokady dla sektorów: ${this.sectors.join(', ')}`);
13
14 // Symulacja aktywacji blokady dla każdego sektora
15 this.affectedSectors = await Promise.all(
16 this.sectors.map(async (sector) => {
17 try {
18 // W rzeczywistym systemie, tu byłoby API call
19 await this.activateSectorLockdown(sector);
20 return {
21 sector,
22 status: 'secured',
23 securedAt: new Date()
24 };
25 } catch (error) {
26 console.error(`Błąd blokady sektora ${sector}: `, error);
27 return {
28 sector,
29 status: 'failed',
30 error: error.message
31 };
32 }
33 })
34 );
35
36 this.active = true;
37
38 // Zwracamy status
39 return {
40 active: this.active,
41 affectedSectors: this.affectedSectors,
42 initializedAt: new Date()
43 };
44 }
45
46 async shutdown() {
47 if (!this.active) {
48 return { success: false, reason: 'Protocol not active' };
49 }
50
51 console.log(`Wyłączanie protokołu blokady dla sektorów: ${this.sectors.join(', ')}`);
52
53 // Symulacja deaktywacji blokady dla każdego sektora
54 await Promise.all(
55 this.sectors.map(async (sector) => {
56 try {
57 // W rzeczywistym systemie, tu byłoby API call
58 await this.deactivateSectorLockdown(sector);
59 } catch (error) {
60 console.error(`Błąd odblokowania sektora ${sector}: `, error);
61 }
62 })
63 );
64
65 this.active = false;
66
67 return {
68 success: true,
69 deactivatedAt: new Date()
70 };
71 }
72
73 // Metoda symulująca aktywację blokady sektora
74 async activateSectorLockdown(sector) {
75 return new Promise((resolve, reject) => {
76 // Symulacja opóźnienia sieciowego i odpowiedzi API
77 setTimeout(() => {
78 if (Math.random() > 0.1) {
79 resolve({
80 sector,
81 status: 'secured',
82 gates: { closed: 4, total: 4 },
83 fences: { energized: true }
84 });
85 } else {
86 reject(new Error(`Błąd blokady sektora ${sector}: Awaria systemu`));
87 }
88 }, 500 + Math.random() * 1000);
89 });
90 }
91
92 // Metoda symulująca deaktywację blokady sektora
93 async deactivateSectorLockdown(sector) {
94 return new Promise((resolve, reject) => {
95 // Symulacja opóźnienia sieciowego i odpowiedzi API
96 setTimeout(() => {
97 if (Math.random() > 0.05) {
98 resolve({
99 sector,
100 status: 'unlocked',
101 gates: { closed: 0, total: 4 },
102 fences: { energized: true } // Ogrodzenia pozostają pod napięciem
103 });
104 } else {
105 reject(new Error(`Błąd odblokowania sektora ${sector}: Awaria systemu`));
106 }
107 }, 300 + Math.random() * 700);
108 });
109 }
110}1// emergencies/dinosaurEscape.js
2export class EmergencyProcedure {
3 constructor(location, options = {}) {
4 this.location = location;
5 this.options = options;
6 this.id = 'EM-' + Date.now().toString(36).toUpperCase();
7 this.status = 'initialized';
8 this.startTime = new Date();
9 }
10
11 async execute() {
12 console.log(`Wykonywanie procedury awaryjnej dla ucieczki dinozaura w lokalizacji ${this.location}`);
13 this.status = 'in_progress';
14
15 try {
16 // 1. Aktywacja alarmu w strefie
17 await this.activateZoneAlarm(this.location);
18
19 // 2. Ewakuacja zwiedzających z zagrożonego obszaru
20 await this.evacuateVisitors(this.location);
21
22 // 3. Wysłanie zespołu bezpieczeństwa
23 const securityTeam = await this.dispatchSecurityTeam(this.location);
24
25 // 4. Aktywacja protokołu blokady w tym i sąsiednich sektorach
26 const adjacentSectors = await this.getAdjacentSectors(this.location);
27 const allSectors = [this.location, ...adjacentSectors];
28 await this.activateLockdown(allSectors);
29
30 // 5. Powiadomienie personelu
31 await this.notifyStaff({
32 type: 'dinosaur_escape',
33 location: this.location,
34 securityTeam,
35 sectors: allSectors
36 });
37
38 this.status = 'completed';
39 console.log(`Procedura awaryjna ${this.id} zakończona pomyślnie`);
40
41 return this.id;
42 } catch (error) {
43 this.status = 'failed';
44 console.error(`Procedura awaryjna ${this.id} nie powiodła się: `, error);
45 throw error;
46 }
47 }
48
49 // Metody pomocnicze...
50 async activateZoneAlarm(zone) {
51 console.log(`Aktywacja alarmu w strefie ${zone}`);
52 // Implementacja...
53 return { success: true, zone };
54 }
55
56 async evacuateVisitors(zone) {
57 console.log(`Ewakuacja zwiedzających ze strefy ${zone}`);
58 // Implementacja...
59 return { success: true, evacuatedCount: Math.floor(Math.random() * 50) + 10 };
60 }
61
62 async dispatchSecurityTeam(zone) {
63 console.log(`Wysyłanie zespołu bezpieczeństwa do strefy ${zone}`);
64 // Implementacja...
65 return {
66 teamId: 'ST-' + Math.floor(Math.random() * 10) + 1,
67 members: Math.floor(Math.random() * 5) + 3,
68 estimatedArrival: new Date(Date.now() + 5 * 60 * 1000)
69 };
70 }
71
72 async getAdjacentSectors(sector) {
73 // W rzeczywistym systemie, pobieralibyśmy to z bazy danych
74 const sectorMap = {
75 'A1': ['A2', 'B1'],
76 'A2': ['A1', 'A3', 'B2'],
77 'B1': ['A1', 'B2', 'C1'],
78 // ... więcej mapowań
79 };
80
81 return sectorMap[sector] || [];
82 }
83
84 async activateLockdown(sectors) {
85 console.log(`Aktywacja blokady w sektorach: ${sectors.join(', ')}`);
86
87 // Dynamicznie importujemy moduł protokołu blokady
88 const LockdownModule = await import('../protocols/lockdown.js');
89 const lockdown = new LockdownModule.default({
90 sectors,
91 reason: 'Ucieczka dinozaura'
92 });
93
94 return lockdown.initialize();
95 }
96
97 async notifyStaff(data) {
98 console.log(`Powiadamianie personelu o sytuacji awaryjnej: `, data);
99 // Implementacja...
100 return { success: true, notifiedCount: Math.floor(Math.random() * 30) + 5 };
101 }
102}Możemy też tworzyć bardziej zaawansowane systemy, w których ścieżki importów są determinowane w czasie wykonania:
1// dynamicModuleLoader.js
2export class ModuleLoader {
3 constructor(basePath = '') {
4 this.basePath = basePath;
5 this.cache = new Map();
6 }
7
8 async load(modulePath, ignoreCache = false) {
9 const fullPath = this.basePath ? `${this.basePath}/${modulePath}` : modulePath;
10
11 // Sprawdź cache, jeśli ignorowanie cache nie jest włączone
12 if (!ignoreCache && this.cache.has(fullPath)) {
13 console.log(`Zwracanie modułu ${fullPath} z cache`);
14 return this.cache.get(fullPath);
15 }
16
17 try {
18 console.log(`Dynamiczne ładowanie modułu: ${fullPath}`);
19 const module = await import(fullPath);
20
21 // Zapisz w cache
22 this.cache.set(fullPath, module);
23
24 return module;
25 } catch (error) {
26 console.error(`Błąd ładowania modułu ${fullPath}: `, error);
27 throw error;
28 }
29 }
30
31 async loadMultiple(modulePaths) {
32 try {
33 const modulePromises = modulePaths.map(path => this.load(path));
34 return await Promise.all(modulePromises);
35 } catch (error) {
36 console.error(`Błąd ładowania wielu modułów: `, error);
37 throw error;
38 }
39 }
40
41 clearCache(modulePath) {
42 if (modulePath) {
43 const fullPath = this.basePath ? `${this.basePath}/${modulePath}` : modulePath;
44 return this.cache.delete(fullPath);
45 } else {
46 // Wyczyść cały cache
47 this.cache.clear();
48 return true;
49 }
50 }
51}
52
53// DinosaurTrackingSystem.js
54import { ModuleLoader } from './dynamicModuleLoader.js';
55
56export class DinosaurTrackingSystem {
57 constructor() {
58 this.moduleLoader = new ModuleLoader('./dinosaurs');
59 this.trackers = new Map();
60 this.activeDinosaurs = new Set();
61 }
62
63 async initialize() {
64 // Ładujemy podstawowe moduły
65 const [baseUtils, trackingCore] = await this.moduleLoader.loadMultiple([
66 './utils.js',
67 './trackingCore.js'
68 ]);
69
70 this.utils = baseUtils;
71 this.trackingCore = trackingCore;
72
73 console.log(`System śledzenia dinozaurów zainicjalizowany.`);
74 }
75
76 async trackDinosaur(dinosaurId, species) {
77 if (this.trackers.has(dinosaurId)) {
78 console.log(`Dinozaur ${dinosaurId} jest już śledzony.`);
79 return this.trackers.get(dinosaurId);
80 }
81
82 try {
83 // Dynamicznie ładujemy moduł śledzenia dla danego gatunku
84 const specificTrackingModule = await this.moduleLoader.load(`./species/${species.toLowerCase()}.js`);
85
86 // Tworzymy i inicjalizujemy tracker dla tego dinozaura
87 const tracker = new specificTrackingModule.default(dinosaurId, {
88 utils: this.utils,
89 core: this.trackingCore
90 });
91
92 await tracker.initialize();
93
94 // Zapisujemy tracker i oznaczamy dinozaura jako aktywnego
95 this.trackers.set(dinosaurId, tracker);
96 this.activeDinosaurs.add(dinosaurId);
97
98 console.log(`Rozpoczęto śledzenie dinozaura ${dinosaurId} (${species}).`);
99 return tracker;
100 } catch (error) {
101 console.error(`Błąd śledzenia dinozaura ${dinosaurId}: `, error);
102
103 // Jeśli nie ma konkretnego modułu dla gatunku, używamy ogólnego
104 try {
105 console.log(`Próba użycia ogólnego modułu śledzenia dla ${species}`);
106 const genericTrackingModule = await this.moduleLoader.load('./genericTracker.js');
107
108 const tracker = new genericTrackingModule.default(dinosaurId, species, {
109 utils: this.utils,
110 core: this.trackingCore
111 });
112
113 await tracker.initialize();
114
115 this.trackers.set(dinosaurId, tracker);
116 this.activeDinosaurs.add(dinosaurId);
117
118 console.log(`Rozpoczęto ogólne śledzenie dinozaura ${dinosaurId} (${species}).`);
119 return tracker;
120 } catch (fallbackError) {
121 console.error(`Nie udało się użyć nawet ogólnego modułu śledzenia: `, fallbackError);
122 throw new Error(`Nie można śledzić dinozaura ${dinosaurId}: ${error.message}`);
123 }
124 }
125 }
126
127 async stopTracking(dinosaurId) {
128 if (!this.trackers.has(dinosaurId)) {
129 console.log(`Dinozaur ${dinosaurId} nie jest śledzony.`);
130 return false;
131 }
132
133 try {
134 const tracker = this.trackers.get(dinosaurId);
135 await tracker.shutdown();
136
137 this.trackers.delete(dinosaurId);
138 this.activeDinosaurs.delete(dinosaurId);
139
140 console.log(`Zatrzymano śledzenie dinozaura ${dinosaurId}.`);
141 return true;
142 } catch (error) {
143 console.error(`Błąd zatrzymania śledzenia dinozaura ${dinosaurId}: `, error);
144 return false;
145 }
146 }
147
148 getActiveTrackingCount() {
149 return this.activeDinosaurs.size;
150 }
151
152 getTrackerInfo(dinosaurId) {
153 const tracker = this.trackers.get(dinosaurId);
154 if (!tracker) {
155 return null;
156 }
157
158 return {
159 dinosaurId,
160 species: tracker.species,
161 lastKnownLocation: tracker.getLastLocation(),
162 status: tracker.getStatus(),
163 isActive: tracker.isActive()
164 };
165 }
166}
167
168// Użycie systemu śledzenia
169async function initTrackingSystem() {
170 const trackingSystem = new DinosaurTrackingSystem();
171 await trackingSystem.initialize();
172
173 // Śledzenie różnych gatunków dinozaurów
174 try {
175 const rexTracker = await trackingSystem.trackDinosaur('rex-01', 'tyrannosaurus');
176 console.log('Status T-Rexa:', rexTracker.getStatus());
177
178 const raptorTracker = await trackingSystem.trackDinosaur('raptor-02', 'velociraptor');
179 console.log('Status Velociraptora:', raptorTracker.getStatus());
180
181 // Nawet jeśli nie mamy specyficznego modułu, system powinien użyć fallbacku
182 const stegoTracker = await trackingSystem.trackDinosaur('stego-01', 'stegosaurus');
183 console.log('Status Stegozaura:', stegoTracker.getStatus());
184
185 console.log(`Aktywne śledzenie: ${trackingSystem.getActiveTrackingCount()} dinozaurów`);
186 } catch (error) {
187 console.error(`Błąd inicjalizacji systemu śledzenia: `, error);
188 }
189}
190
191// Inicjalizacja systemu
192initTrackingSystem();W nowoczesnych przeglądarkach dynamiczny import działa natywnie:
1// Przykład dla przeglądarki
2document.getElementById('btnActivateLockdown').addEventListener('click', async () => {
3 try {
4 const lockdownModule = await import('./security/lockdown.js');
5 const lockdown = new lockdownModule.default();
6 lockdown.activateForSectors(['A1', 'B2']);
7 } catch (error) {
8 console.error('Nie udało się załadować modułu blokady:', error);
9 }
10});Node.js od wersji 13.2.0 oficjalnie wspiera dynamiczne importy:
1// Przykład dla Node.js
2async function runDinosaurAnalysis(species) {
3 try {
4 // Dynamiczny import modułu analizy dla danego gatunku
5 const analyzer = await import(`./analyzers/${species.toLowerCase()}.js`);
6 return analyzer.analyzeGenome();
7 } catch (error) {
8 console.error(`Nie ma analizatora dla gatunku ${species}: `, error);
9 // Użyj ogólnego analizatora
10 const genericAnalyzer = await import('./analyzers/generic.js');
11 return genericAnalyzer.analyzeGenome(species);
12 }
13}
14
15// Użycie
16runDinosaurAnalysis('velociraptor')
17 .then(results => console.log('Wyniki analizy genomu:', results))
18 .catch(error => console.error('Błąd analizy:', error));Bundlery jak Webpack, Rollup czy Parcel automatycznie wykrywają dynamiczne importy i dzielą kod na mniejsze fragmenty (chunks):
1// Webpack automatycznie zrozumie i obsłuży ten import
2const loadAdminPanel = async () => {
3 // Zostanie wygenerowany osobny chunk dla adminPanel
4 const adminModule = await import(/* webpackChunkName: "admin" */ './adminPanel');
5 return new adminModule.default();
6};
7
8// Można nawet wskazać priorytet ładowania
9const prefetchReportGenerator = () => {
10 // Pobierz moduł z wyprzedzeniem, ale wykonaj dopiero gdy potrzebny
11 import(/* webpackPrefetch: true */ './reportGenerator');
12};Dynamiczne importowanie modułów to potężna funkcja, która pozwala na większą elastyczność i wydajność w aplikacjach JavaScript. W kontekście naszego Parku Jurajskiego, daje nam możliwość budowania systemów, które mogą dynamicznie reagować na różne sytuacje, co jest kluczowe dla bezpieczeństwa parku pełnego niebezpiecznych dinozaurów!
Dzięki dynamicznym importom możemy:
W następnym ćwiczeniu zajmiemy się narzędziami do debugowania JavaScript, które będą nieocenione, gdy nastąpi jakaś awaria w naszych systemach zarządzania parkiem!