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

import export Modern
📚

CommonJS

Node.js module system

require() module.exports Node.js
🔧

AMD

Asynchronous Module Definition

define() RequireJS Browser
🌐

UMD

Universal Module Definition

Universal Compatible Flexible

🔹 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

🧠 Test Your Knowledge

How do you export a function in ES6 modules?