JavaScript and TypeScript course Β· Module 5: Advanced JavaScript
Browser Console and Its Functions
In this lesson6
Managing Jurassic Park is no easy task. When problems arise in the dinosaur tracking system or we need to quickly diagnose why the lockdown protocol isn't starting correctly, debugging is a critical skill. One of the most important diagnostic tools in JavaScript is the browser console.
In this exercise we'll learn about a tool that will be your best friend when searching for and solving problems - the browser developer console.
Opening the Developer Console
Before we start using the console, we need to know how to open it:
- Chrome/Edge: <kbd>F12</kbd> or <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>J</kbd> (Windows/Linux) or <kbd>Cmd</kbd>+<kbd>Option</kbd>+<kbd>J</kbd> (Mac)
- Firefox: <kbd>F12</kbd> or <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>K</kbd> (Windows/Linux) or <kbd>Cmd</kbd>+<kbd>Option</kbd>+<kbd>K</kbd> (Mac)
- Safari: <kbd>Cmd</kbd>+<kbd>Option</kbd>+<kbd>C</kbd> (you must first enable developer tools in settings)
After opening you'll see several tabs, including "Console". That's where we'll focus.
Basic Console Functions
1. console.log() - Your Best Friend
The most commonly used console function is console.log(). It displays values in the console, which is indispensable during debugging:
1// Displaying simple values
2console.log("Dinosaur tracking system started");
3console.log(42); // number
4console.log(true); // boolean value
5
6// Displaying multiple values at once
7const dinosaur = { name: "Rex", type: "T-Rex", status: "contained" };
8console.log("Dinosaur data:", dinosaur, "Update:", new Date());
9
10// String interpolation
11const sector = "B7";
12const threat = "high";
13console.log(`Dinosaur detected in sector ${sector}. Threat level: ${threat}`);In our Jurassic Park system we can use console.log() to track various events:
1function trackDinosaur(id, location) {
2 console.log(`Tracking dinosaur #${id} at location ${location}`);
3
4 // Tracking logic...
5 const status = checkContainment(id);
6
7 if (status !== "contained") {
8 console.log(`ALERT: Dinosaur #${id} is not in its enclosure! Current status: ${status}`);
9 }
10
11 return status;
12}2. console.error(), console.warn(), console.info()
In addition to the standard log, we have special methods for different message levels:
1// Errors - usually displayed in red
2console.error("CRITICAL ERROR: Fence system failure in T-Rex sector!");
3
4// Warnings - usually displayed in yellow
5console.warn("Warning: Motion sensor battery level dropping below 20%");
6
7// Info - often distinguished from regular logs
8console.info("Info: Technical system review scheduled for tomorrow, 8:00");Using them helps visually distinguish message types in the console, which is especially important when dealing with large volumes of logs.
3. console.table() - Clean Display of Tabular Data
When dealing with arrays of objects, console.table() is invaluable:
1// Array of dinosaurs in our park
2const dinosaurs = [
3 { id: 1, name: "Rex", species: "T-Rex", danger: 9, location: "Enclosure A" },
4 { id: 2, name: "Blue", species: "Velociraptor", danger: 8, location: "Enclosure B" },
5 { id: 3, name: "Delta", species: "Velociraptor", danger: 8, location: "Enclosure B" },
6 { id: 4, name: "Echo", species: "Velociraptor", danger: 7, location: "Enclosure B" },
7 { id: 5, name: "Trike", species: "Triceratops", danger: 4, location: "Enclosure C" }
8];
9
10// Displays a beautiful table with the data
11console.table(dinosaurs);
12
13// We can also select specific columns
14console.table(dinosaurs, ["name", "species", "danger"]);This is especially useful for data analysis, checking API query results, or reviewing configurations.
4. console.group() - Grouping Logs
When we have many related logs, we can group them for clarity:
1// Monitoring a specific dinosaur
2function monitorDinosaur(dinosaur) {
3 console.group(`Monitoring: ${dinosaur.name} (${dinosaur.species})`);
4
5 console.log(`Location: ${dinosaur.location}`);
6 console.log(`Danger level: ${dinosaur.danger}/10`);
7
8 const healthStatus = checkHealth(dinosaur.id);
9 console.log(`Health status: ${healthStatus.status}`);
10
11 if (healthStatus.issues.length > 0) {
12 console.warn(`Health issues detected: ${healthStatus.issues.join(', ')}`);
13 }
14
15 const securityStatus = checkSecurity(dinosaur.location);
16 console.log(`Security status: ${securityStatus.status}`);
17
18 if (securityStatus.issues.length > 0) {
19 console.error(`Security issues: ${securityStatus.issues.join(', ')}`);
20 }
21
22 console.groupEnd();
23
24 return { healthStatus, securityStatus };
25}
26
27// Grouping can also be nested
28function monitorAllDinosaurs(dinosaurs) {
29 console.group('Monitoring all dinosaurs');
30
31 dinosaurs.forEach(dino => {
32 monitorDinosaur(dino);
33 });
34
35 console.groupEnd();
36}
37
38monitorAllDinosaurs(dinosaurs);You can also start a group collapsed using console.groupCollapsed(), which is useful with many groups.
5. console.time() and console.timeEnd() - Measuring Execution Time
Sometimes we need to know how long certain operations take:
1// Measuring module load time
2console.time('Loading tracking module');
3
4loadTrackingModule()
5 .then(() => {
6 console.timeEnd('Loading tracking module');
7 // Displays e.g.: "Loading tracking module: 235.41ms"
8 });
9
10// We can have multiple parallel timers
11console.time('System initialization');
12console.time('Data processing');
13
14initSystem()
15 .then(() => {
16 console.timeEnd('System initialization');
17 return processData();
18 })
19 .then(() => {
20 console.timeEnd('Data processing');
21 });This is extremely useful for identifying bottlenecks in applications and optimizing performance.
6. console.trace() - Call Stack Tracing
When you don't know exactly where a function was called from:
1function monitorFenceStatus(sectorId) {
2 console.trace(`Checking fence status in sector ${sectorId}`);
3 // Rest of code...
4}
5
6function checkAllFences() {
7 const sectors = ['A1', 'B2', 'C3'];
8 sectors.forEach(monitorFenceStatus);
9}
10
11function dailySecurityCheck() {
12 checkAllFences();
13}
14
15dailySecurityCheck();console.trace() will display the full call stack, showing the exact execution path, which is invaluable when debugging complex calls.
7. console.assert() - Conditional Debug Messages
Checks a condition and displays an error when the condition is false:
1function feedDinosaur(dinosaur, foodAmount) {
2 // Make sure the food amount is sufficient for the species
3 console.assert(
4 foodAmount >= getMinimumFoodRequirement(dinosaur.species),
5 `Insufficient food for ${dinosaur.name}! ` +
6 `Required minimum: ${getMinimumFoodRequirement(dinosaur.species)}kg, ` +
7 `Provided: ${foodAmount}kg`
8 );
9
10 // Rest of code...
11}
12
13feedDinosaur(dinosaurs[0], 5); // If 5kg is too little, we'll see an errorThis is useful for early detection of potential problems without stopping program execution.
8. console.count() - Counting Calls
Counting how many times a function or code block has been called:
1function checkFenceVoltage(sectorId) {
2 console.count(`Voltage check in sector ${sectorId}`);
3 // Rest of code...
4}
5
6// Simulate regular checks
7setInterval(() => checkFenceVoltage('A1'), 5000);
8setInterval(() => checkFenceVoltage('B2'), 8000);After each call we'll see in the console something like:
1Voltage check in sector A1: 1
2Voltage check in sector A1: 2
3Voltage check in sector B2: 1
4Voltage check in sector A1: 3We can reset the counter using console.countReset('name').
9. console.dir() - Displaying Object Properties
When we want to see the full structure of an object:
1const parkSystem = {
2 name: "Jurassic Park",
3 sectors: {
4 A: { dinosaurs: [/*...*/], status: "secure" },
5 B: { dinosaurs: [/*...*/], status: "alert" }
6 },
7 security: {
8 fences: { status: "online", voltage: 10000 },
9 cameras: { operational: 45, offline: 3 }
10 }
11};
12
13// Displays an interactive, expandable object structure
14console.dir(parkSystem);This function is especially useful for complex objects, as it allows browsing nested properties.
10. Console Message Formatting
The console also supports basic formatting with format specifiers:
1// Styling text with CSS
2console.log(
3 "%cWARNING! %cCritical danger level %cin sector B!",
4 "color: red; font-size: 20px; font-weight: bold;",
5 "color: orange; font-size: 16px;",
6 "color: black; font-weight: bold;"
7);
8
9// Displaying variables in a message
10console.log("Dinosaur %s has danger level %d", "Rex", 9);Advanced Console Features
1. Filtering Messages
Most browser consoles allow filtering displayed messages. We can filter by:
- Level (Error, Warning, Info, Log)
- Text (typing a search phrase)
- Source (e.g. only from a specific file)
This is extremely useful when dealing with large volumes of logs.
2. Saving to File
Console messages can usually be saved to a file, which is useful for log analysis:
- Right-click in the console
- Select "Save as..."
3. Clearing the Console
The console can be cleared in several ways:
- Clicking the crossed-circle icon in the console
- Pressing <kbd>Ctrl</kbd>+<kbd>L</kbd> (when the console is active)
- Using code:
console.clear()
4. Console as a REPL Environment
The browser console also works as a REPL (Read-Eval-Print Loop), meaning we can execute JavaScript code directly in it:
1// Directly in console
2const dinos = [{name: "Rex"}, {name: "Blue"}];
3dinos.filter(d => d.name === "Blue");
4
5// Defining functions
6function alertSecurity(message) {
7 return `[SECURITY ALERT] ${message} - ${new Date().toISOString()}`;
8}
9
10// Using the function
11alertSecurity("Fence breach in sector C2");This is extremely useful for testing small code snippets or debugging without modifying source code.
Practical Implementation in Our Jurassic Park System
Let's create a practical implementation of a logging system for our Jurassic Park that makes use of various console functions:
1// Logger for the Jurassic Park system
2class JurassicLogger {
3 constructor(moduleName) {
4 this.moduleName = moduleName;
5 this.logCount = 0;
6 this.errorCount = 0;
7 this.warnCount = 0;
8 }
9
10 log(...args) {
11 this.logCount++;
12 console.log(`[${this.moduleName}] `, ...args);
13 }
14
15 error(...args) {
16 this.errorCount++;
17 console.error(`[${this.moduleName}] ERROR:`, ...args);
18 }
19
20 warn(...args) {
21 this.warnCount++;
22 console.warn(`[${this.moduleName}] WARNING:`, ...args);
23 }
24
25 info(...args) {
26 console.info(`[${this.moduleName}] INFO:`, ...args);
27 }
28
29 startGroup(label) {
30 console.group(`[${this.moduleName}] ${label}`);
31 }
32
33 endGroup() {
34 console.groupEnd();
35 }
36
37 startTimer(label) {
38 console.time(`[${this.moduleName}] ${label}`);
39 }
40
41 endTimer(label) {
42 console.timeEnd(`[${this.moduleName}] ${label}`);
43 }
44
45 table(data, columns) {
46 console.log(`[${this.moduleName}] Tabular data:`);
47 console.table(data, columns);
48 }
49
50 getStats() {
51 return {
52 moduleName: this.moduleName,
53 logs: this.logCount,
54 errors: this.errorCount,
55 warnings: this.warnCount
56 };
57 }
58
59 trace(message) {
60 console.log(`[${this.moduleName}] TRACE: ${message}`);
61 console.trace();
62 }
63
64 assert(condition, message) {
65 console.assert(condition, `[${this.moduleName}] Assertion failed: ${message}`);
66 }
67
68 // Special formatting for security alerts
69 securityAlert(message, level = 'warning') {
70 const styles = {
71 warning: "background: #FFA500; color: black; padding: 2px 5px; border-radius: 3px;",
72 critical: "background: #FF0000; color: white; padding: 2px 5px; border-radius: 3px; font-weight: bold;",
73 info: "background: #0066FF; color: white; padding: 2px 5px; border-radius: 3px;"
74 };
75
76 console.log(
77 `%c[${this.moduleName}] SECURITY ALERT %c${message}`,
78 styles[level] || styles.warning,
79 "color: black;"
80 );
81 }
82}
83
84// Example usage
85const securityLogger = new JurassicLogger('ParkSecurity');
86const dinosaurLogger = new JurassicLogger('DinosaurTracker');
87const systemLogger = new JurassicLogger('MainSystem');
88
89// System initialization
90systemLogger.startTimer('System initialization');
91systemLogger.log('Starting Jurassic Park system initialization...');
92
93setTimeout(() => {
94 systemLogger.info('Subsystems started');
95 systemLogger.endTimer('System initialization');
96
97 // Dinosaur information
98 const dinoData = [
99 { id: 'TRX-01', name: 'Rex', species: 'T-Rex', status: 'contained', healthLevel: 92 },
100 { id: 'VEL-01', name: 'Blue', species: 'Velociraptor', status: 'contained', healthLevel: 87 },
101 { id: 'VEL-02', name: 'Delta', species: 'Velociraptor', status: 'sedated', healthLevel: 65 },
102 { id: 'TRI-01', name: 'Sarah', species: 'Triceratops', status: 'contained', healthLevel: 95 }
103 ];
104
105 dinosaurLogger.startGroup('Dinosaur status report');
106 dinosaurLogger.table(dinoData);
107
108 // Check dinosaur health
109 dinoData.forEach(dino => {
110 dinosaurLogger.startGroup(`Dinosaur: ${dino.name}`);
111
112 if (dino.healthLevel < 70) {
113 dinosaurLogger.warn(`Dinosaur ${dino.name} health level is low: ${dino.healthLevel}%`);
114 } else {
115 dinosaurLogger.log(`Health status: ${dino.healthLevel}%`);
116 }
117
118 if (dino.status !== 'contained') {
119 dinosaurLogger.error(`Dinosaur ${dino.name} is not in its enclosure! Status: ${dino.status}`);
120 securityLogger.securityAlert(`Dinosaur ${dino.name} (${dino.species}) status: ${dino.status}`, 'critical');
121 }
122
123 dinosaurLogger.endGroup();
124 });
125
126 dinosaurLogger.endGroup();
127
128 // Check security systems
129 securityLogger.startGroup('Security systems');
130
131 const fenceStatus = { sector: 'B', voltage: 9800, status: 'active' };
132 securityLogger.log(`Fence status in sector ${fenceStatus.sector}: ${fenceStatus.status}`);
133 securityLogger.assert(
134 fenceStatus.voltage >= 10000,
135 `Fence voltage in sector ${fenceStatus.sector} is too low: ${fenceStatus.voltage}V (min. 10000V)`
136 );
137
138 securityLogger.endGroup();
139
140 // Display log stats
141 systemLogger.startGroup('Log statistics');
142 console.table([
143 securityLogger.getStats(),
144 dinosaurLogger.getStats(),
145 systemLogger.getStats()
146 ]);
147 systemLogger.endGroup();
148
149}, 2000);Production and Development Logging
In real applications it's worth separating development logging from production logging:
1// logger.js
2class Logger {
3 constructor(isProduction = process.env.NODE_ENV === 'production') {
4 this.isProduction = isProduction;
5 }
6
7 log(...args) {
8 if (!this.isProduction) {
9 console.log(...args);
10 }
11 }
12
13 // For critical errors, we log even in production
14 error(...args) {
15 console.error(...args);
16
17 if (this.isProduction) {
18 // In production we can send errors to a monitoring service
19 this.sendToErrorMonitoring(args);
20 }
21 }
22
23 sendToErrorMonitoring(errorData) {
24 // Implementation for sending to Sentry, LogRocket, etc.
25 }
26}
27
28export default new Logger();Summary
The browser console is a powerful tool that greatly simplifies debugging and monitoring JavaScript applications. In the context of our Jurassic Park, good logging practices can be the difference between a smoothly running park and... well, the scenario from the movies!
Key functions to remember:
console.log()- basic loggingconsole.error(),console.warn(),console.info()- different message levelsconsole.table()- clean data displayconsole.group()- organizing related logsconsole.time()andconsole.timeEnd()- measuring performanceconsole.trace()- diagnosing where a call comes fromconsole.assert()- conditional debug messages
Remember to regularly use the console during development - it will help you detect and fix bugs faster, before the dinosaurs find a hole in your code!
Code for this lesson: main.js
1// Re-exporting and module aggregation - Jurassic Park
2// Creating "index" modules for easier importing
3
4console.log("Re-exporting and Module Aggregation");
5console.log("Module structure organization\n");
6
7// ===========================================
8// BASE MODULES
9// ===========================================
10
11// === types/DinosaurTypes.js ===
12const DinosaurTypes = {
13 CARNIVORE: 'carnivore',
14 HERBIVORE: 'herbivore',
15 OMNIVORE: 'omnivore'
16};
17
18const DangerLevels = {
19 LOW: 1,
20 MEDIUM: 5,
21 HIGH: 7,
22 CRITICAL: 9
23};
24
25// === models/Dinosaur.js ===
26class Dinosaur {
27 constructor(name, species, type, dangerLevel) {
28 this.name = name;
29 this.species = species;
30 this.type = type;
31 this.dangerLevel = dangerLevel;
32 this.health = 100;
33 this.id = Math.random().toString(36).substr(2, 9);
34 }
35
36 getInfo() {
37 return `${this.name} (${this.species}) - Danger: ${this.dangerLevel}/10`;
38 }
39}
40
41// === models/Enclosure.js ===
42class Enclosure {
43 constructor(id, name, capacity) {
44 this.id = id;
45 this.name = name;
46 this.capacity = capacity;
47 this.dinosaurs = [];
48 }
49
50 addDinosaur(dinosaur) {
51 if (this.dinosaurs.length >= this.capacity) {
52 throw new Error('Enclosure is full');
53 }
54 this.dinosaurs.push(dinosaur);
55 }
56
57 getStatus() {
58 return `${this.name}: ${this.dinosaurs.length}/${this.capacity} dinosaurs`;
59 }
60}
61
62// === models/Visitor.js ===
63class Visitor {
64 constructor(name, age, ticketType) {
65 this.name = name;
66 this.age = age;
67 this.ticketType = ticketType;
68 this.id = Math.random().toString(36).substr(2, 9);
69 }
70
71 getDetails() {
72 return `${this.name}, ${this.age} years old (${this.ticketType} ticket)`;
73 }
74}
75
76// === utils/validators.js ===
77function validateDinosaur(data) {
78 const { name, species, type, dangerLevel } = data;
79 const errors = [];
80
81 if (!name || typeof name !== 'string') errors.push('Invalid name');
82 if (!species || typeof species !== 'string') errors.push('Invalid species');
83 if (!Object.values(DinosaurTypes).includes(type)) errors.push('Invalid type');
84 if (dangerLevel < 1 || dangerLevel > 10) errors.push('Danger level must be 1-10');
85
86 return { valid: errors.length === 0, errors };
87}
88
89function validateEnclosure(data) {
90 const { id, name, capacity } = data;
91 const errors = [];
92
93 if (!id || typeof id !== 'string') errors.push('Invalid id');
94 if (!name || typeof name !== 'string') errors.push('Invalid name');
95 if (!capacity || capacity < 1) errors.push('Capacity must be at least 1');
96
97 return { valid: errors.length === 0, errors };
98}
99
100// === utils/formatters.js ===
101function formatDinosaurReport(dinosaur) {
102 return {
103 id: dinosaur.id,
104 name: dinosaur.name,
105 species: dinosaur.species,
106 type: dinosaur.type,
107 dangerLevel: dinosaur.dangerLevel,
108 health: `${dinosaur.health}%`,
109 status: dinosaur.health > 70 ? 'Good' : 'Needs attention'
110 };
111}
112
113function formatEnclosureReport(enclosure) {
114 return {
115 id: enclosure.id,
116 name: enclosure.name,
117 occupancy: `${enclosure.dinosaurs.length}/${enclosure.capacity}`,
118 dinosaurs: enclosure.dinosaurs.map(d => d.name),
119 status: enclosure.dinosaurs.length >= enclosure.capacity ? 'Full' : 'Available'
120 };
121}
122
123// ===========================================
124// AGGREGATING MODULES (BARREL EXPORTS)
125// ===========================================
126
127// === models/index.js - Aggregating all models ===
128// Re-exporting all models from one place
129const ModelsModule = {
130 Dinosaur,
131 Enclosure,
132 Visitor
133};
134
135console.log("Models Module:");
136console.log(" - Dinosaur");
137console.log(" - Enclosure");
138console.log(" - Visitor\n");
139
140// === types/index.js - Type aggregation ===
141const TypesModule = {
142 DinosaurTypes,
143 DangerLevels
144};
145
146console.log("Types Module:");
147console.log(" - DinosaurTypes");
148console.log(" - DangerLevels\n");
149
150// === utils/index.js - Aggregating utilities ===
151const UtilsModule = {
152 // validators
153 validateDinosaur,
154 validateEnclosure,
155 // formatters
156 formatDinosaurReport,
157 formatEnclosureReport
158};
159
160console.log("Utils Module:");
161console.log(" - validateDinosaur");
162console.log(" - validateEnclosure");
163console.log(" - formatDinosaurReport");
164console.log(" - formatEnclosureReport\n");
165
166// === index.js - MAIN AGGREGATING MODULE ===
167// Re-export everything from submodules
168const JurassicParkSDK = {
169 // Models
170 ...ModelsModule,
171 // Types
172 ...TypesModule,
173 // Utils
174 ...UtilsModule
175};
176
177console.log("Main SDK Module (All exports):");
178console.log(" All models");
179console.log(" All types");
180console.log(" All utilities\n");
181
182// ===========================================
183// USAGE DEMONSTRATION
184// ===========================================
185
186console.log("=== RE-EXPORTING DEMO ===\n");
187
188// Instead of importing from many places:
189console.log("WITHOUT re-exports (many imports):");
190console.log("import { Dinosaur } from './models/Dinosaur.js';");
191console.log("import { Enclosure } from './models/Enclosure.js';");
192console.log("import { DinosaurTypes } from './types/DinosaurTypes.js';");
193console.log("import { validateDinosaur } from './utils/validators.js';");
194console.log("import { formatDinosaurReport } from './utils/formatters.js';\n");
195
196// We can import everything from one place:
197console.log("WITH re-exports (one import):");
198console.log("import {");
199console.log(" Dinosaur, Enclosure,");
200console.log(" DinosaurTypes,");
201console.log(" validateDinosaur, formatDinosaurReport");
202console.log("} from './index.js';\n");
203
204console.log("=== PRACTICAL USAGE ===\n");
205
206// Creating a dinosaur
207const dinoData = {
208 name: 'Rexy',
209 species: 'Tyrannosaurus Rex',
210 type: JurassicParkSDK.DinosaurTypes.CARNIVORE,
211 dangerLevel: JurassicParkSDK.DangerLevels.CRITICAL
212};
213
214console.log("1. Validating the dinosaur data:");
215const validation = JurassicParkSDK.validateDinosaur(dinoData);
216console.log(` Valid: ${validation.valid}`);
217
218if (validation.valid) {
219 const trex = new JurassicParkSDK.Dinosaur(
220 dinoData.name,
221 dinoData.species,
222 dinoData.type,
223 dinoData.dangerLevel
224 );
225
226 console.log(`\n2. Dinosaur created: ${trex.getInfo()}`);
227
228 const report = JurassicParkSDK.formatDinosaurReport(trex);
229 console.log("\n3. Dinosaur report:");
230 console.log(JSON.stringify(report, null, 2));
231}
232
233// Creating paddock
234console.log("\n4. Creating paddock:");
235const enclosureData = {
236 id: 'ENC-001',
237 name: 'T-Rex Paddock',
238 capacity: 2
239};
240
241const encValidation = JurassicParkSDK.validateEnclosure(enclosureData);
242console.log(` Valid: ${encValidation.valid}`);
243
244if (encValidation.valid) {
245 const paddock = new JurassicParkSDK.Enclosure(
246 enclosureData.id,
247 enclosureData.name,
248 enclosureData.capacity
249 );
250
251 const trex = new JurassicParkSDK.Dinosaur(
252 'Rexy',
253 'T-Rex',
254 JurassicParkSDK.DinosaurTypes.CARNIVORE,
255 9
256 );
257
258 paddock.addDinosaur(trex);
259
260 const encReport = JurassicParkSDK.formatEnclosureReport(paddock);
261 console.log("\n5. Paddock report:");
262 console.log(JSON.stringify(encReport, null, 2));
263}
264
265console.log("\n=== BENEFITS OF RE-EXPORTING ===\n");
266
267console.log("Simpler imports:");
268console.log(" - One import instead of many");
269console.log(" - Cleaner code\n");
270
271console.log("Better DX (Developer Experience):");
272console.log(" - Easier API discovery");
273console.log(" - Intuitive structure\n");
274
275console.log("Easier refactoring:");
276console.log(" - Changes to the internal structure don't affect users");
277console.log(" - The public API stays stable\n");
278
279console.log("Tree Shaking:");
280console.log(" - Bundlers can remove unused code");
281console.log(" - Smaller bundle size\n");
282
283console.log("=== EXAMPLE PATTERNS ===\n");
284
285console.log("// Basic re-export");
286console.log("export { Dinosaur } from './Dinosaur.js';\n");
287
288console.log("// Re-export with an alias");
289console.log("export { Dinosaur as Dino } from './Dinosaur.js';\n");
290
291console.log("// Re-export everything");
292console.log("export * from './models.js';\n");
293
294console.log("// Re-export with aggregation");
295console.log("export { Dinosaur } from './Dinosaur.js';");
296console.log("export { Enclosure } from './Enclosure.js';");
297console.log("export { Visitor } from './Visitor.js';\n");
298
299console.log("// Mixed export (default + named)");
300console.log("export { default as Dinosaur, DinosaurTypes } from './Dinosaur.js';\n");
301
302console.log("Demo completed!");Spotted a mistake in this lesson?
Check yourself
Answer the questions from this lesson. Pick an answer to see right away whether it is correct.
1. Which browser tool allows you to measure the execution time of a JavaScript code snippet?