JavaScript Modules
Organizing and reusing JavaScript code
📦 What are JavaScript Modules?
Modules let you split your JavaScript code into separate files and reuse them. Think of modules as building blocks for your applications!
// math.js - A simple module
export function add(a, b) {
return a + b;
}
// main.js - Using the module
import { add } from './math.js';
console.log(add(5, 3)); // 8
Types of Modules
ES6 Modules
Modern JavaScript modules
CommonJS
Node.js module system
AMD
Asynchronous Module Definition
UMD
Universal Module Definition
🔹 ES6 Modules (Modern Way)
The modern standard for JavaScript modules:
🔸 Exporting from a Module
// utils.js - Creating a module
export function greet(name) {
return `Hello, ${name}!`;
}
export function capitalize(text) {
return text.charAt(0).toUpperCase() + text.slice(1);
}
export const PI = 3.14159;
// Default export
export default function calculate(x, y) {
return x * y;
}
🔸 Importing from a Module
// main.js - Using the module
import calculate, { greet, capitalize, PI } from './utils.js';
console.log(greet("Alice")); // Hello, Alice!
console.log(capitalize("hello")); // Hello
console.log(PI); // 3.14159
console.log(calculate(5, 3)); // 15
Output:
Hello, Alice! Hello 3.14159 15
🔹 Different Export Styles
Various ways to export functions and variables:
🔸 Named Exports
// math.js
export function add(a, b) {
return a + b;
}
export function subtract(a, b) {
return a - b;
}
// Or export all at once
function multiply(a, b) {
return a * b;
}
function divide(a, b) {
return a / b;
}
export { multiply, divide };
🔸 Default Exports
// calculator.js - One main export per file
class Calculator {
add(a, b) {
return a + b;
}
subtract(a, b) {
return a - b;
}
}
export default Calculator;
// Using default export
import Calculator from './calculator.js';
const calc = new Calculator();
console.log(calc.add(10, 5)); // 15
🔹 Import Variations
Different ways to import modules:
// Import specific functions
import { add, subtract } from './math.js';
// Import with different names
import { add as sum, subtract as minus } from './math.js';
// Import everything
import * as MathUtils from './math.js';
console.log(MathUtils.add(5, 3));
// Import default and named exports
import Calculator, { PI, greet } from './utils.js';
// Dynamic imports (advanced)
async function loadModule() {
const module = await import('./math.js');
console.log(module.add(2, 3));
}
🔹 Real-World Module Example
A practical example of organizing code with modules:
🔸 User Module
// user.js
export class User {
constructor(name, email) {
this.name = name;
this.email = email;
this.id = Math.random().toString(36).substr(2, 9);
}
getInfo() {
return `${this.name} (${this.email})`;
}
}
export function validateEmail(email) {
return email.includes('@') && email.includes('.');
}
🔸 Database Module
// database.js
const users = [];
export function saveUser(user) {
users.push(user);
console.log(`User ${user.name} saved!`);
}
export function getAllUsers() {
return users;
}
export function findUserById(id) {
return users.find(user => user.id === id);
}
🔸 Main Application
// app.js
import { User, validateEmail } from './user.js';
import { saveUser, getAllUsers } from './database.js';
// Create and save users
if (validateEmail('[email protected]')) {
const alice = new User('Alice', '[email protected]');
saveUser(alice);
}
const bob = new User('Bob', '[email protected]');
saveUser(bob);
// Display all users
console.log('All users:', getAllUsers());
Output:
User Alice saved!
User Bob saved!
All users: [
{ name: 'Alice', email: '[email protected]', id: 'abc123def' },
{ name: 'Bob', email: '[email protected]', id: 'xyz789ghi' }
]
🔹 Module Best Practices
Tips for writing clean, maintainable modules:
Module Guidelines:
- One purpose per module - Keep modules focused
- Clear naming - Use descriptive file and function names
- Small modules - Easier to understand and test
- Avoid circular dependencies - Module A imports B, B imports A
- Use default exports sparingly - Named exports are more explicit
🔸 Good Module Structure
// Good: Clear, focused module
// string-utils.js
export function capitalize(str) {
return str.charAt(0).toUpperCase() + str.slice(1);
}
export function reverse(str) {
return str.split('').reverse().join('');
}
export function truncate(str, length) {
return str.length > length ? str.slice(0, length) + '...' : str;
}
// Usage is clear and predictable
import { capitalize, truncate } from './string-utils.js';
🔹 Using Modules in HTML
How to use ES6 modules in web browsers:
<!-- index.html -->
<!DOCTYPE html>
<html>
<head>
<title>Module Example</title>
</head>
<body>
<h1>JavaScript Modules Demo</h1>
<!-- Important: type="module" -->
<script type="module" src="app.js"></script>
</body>
</html>
Important Notes:
-
Use
type="module"in script tags - Modules must be served over HTTP (not file://)
- Modules are automatically in strict mode
- Each module has its own scope