JavaScript Modules (ES6+)
Master ES6 modules, import/export syntax, dynamic imports, and modern module patterns for building scalable applications
45 min•By Priygop Team•Last updated: Feb 2026
Module System
ES6 modules provide a standardized way to organize and share code between files. They offer better encapsulation, explicit dependencies, and improved tooling support compared to traditional script tags.
Module Concepts
- Export Statements: Named and default exports
- Import Statements: Named and default imports
- Dynamic Imports: Load modules on demand
- Module Bundlers: Webpack, Vite, Rollup integration
- Tree Shaking: Remove unused code
- Circular Dependencies: Avoid and resolve issues
Module Examples
Example
// math.js - Module with named exports
export const add = (a, b) => a + b;
export const subtract = (a, b) => a - b;
export const multiply = (a, b) => a * b;
export const divide = (a, b) => a / b;
// constants.js - Module with default export
const PI = 3.14159;
const E = 2.71828;
export default { PI, E };
// utils.js - Mixed exports
export const formatCurrency = (amount) => `$${amount.toFixed(2)}`;
export const formatDate = (date) => date.toLocaleDateString();
const helper = {
validateEmail: (email) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email),
generateId: () => Math.random().toString(36).substr(2, 9)
};
export default helper;
// main.js - Importing modules
import { add, multiply } from './math.js';
import mathConstants from './constants.js';
import helper, { formatCurrency } from './utils.js';
console.log(add(5, 3)); // 8
console.log(multiply(4, 2)); // 8
console.log(mathConstants.PI); // 3.14159
console.log(formatCurrency(123.456)); // "$123.46"
console.log(helper.validateEmail('test@example.com')); // true
// Dynamic imports
async function loadModule(moduleName) {
try {
const module = await import(`./${moduleName}.js`);
return module;
} catch (error) {
console.error(`Failed to load module: ${moduleName}`, error);
return null;
}
}
// Usage
const mathModule = await loadModule('math');
if (mathModule) {
console.log(mathModule.add(10, 5)); // 15
}
// Re-exporting
// index.js - Barrel export
export { add, subtract } from './math.js';
export { formatCurrency } from './utils.js';
export { default as constants } from './constants.js';
// Import from barrel
import { add, formatCurrency, constants } from './index.js';Practice Exercise: Modules
Example
// Exercise: Build a Modular Calculator
// calculator/operations.js
export const add = (a, b) => a + b;
export const subtract = (a, b) => a - b;
export const multiply = (a, b) => a * b;
export const divide = (a, b) => {
if (b === 0) throw new Error('Division by zero');
return a / b;
};
export const power = (base, exponent) => Math.pow(base, exponent);
export const sqrt = (number) => {
if (number < 0) throw new Error('Cannot calculate square root of negative number');
return Math.sqrt(number);
};
// calculator/validator.js
export const validateNumber = (value) => {
if (typeof value !== 'number' || isNaN(value)) {
throw new Error('Invalid number');
}
return true;
};
export const validateOperands = (a, b) => {
validateNumber(a);
validateNumber(b);
};
// calculator/formatter.js
export const formatResult = (result, precision = 2) => {
return Number(result.toFixed(precision));
};
export const formatExpression = (operation, a, b, result) => {
return `${a} ${operation} ${b} = ${result}`;
};
// calculator/index.js
import * as operations from './operations.js';
import * as validator from './validator.js';
import * as formatter from './formatter.js';
export class Calculator {
constructor() {
this.history = [];
}
calculate(operation, a, b) {
try {
validator.validateOperands(a, b);
let result;
switch (operation) {
case 'add':
result = operations.add(a, b);
break;
case 'subtract':
result = operations.subtract(a, b);
break;
case 'multiply':
result = operations.multiply(a, b);
break;
case 'divide':
result = operations.divide(a, b);
break;
case 'power':
result = operations.power(a, b);
break;
default:
throw new Error(`Unknown operation: ${operation}`);
}
const formattedResult = formatter.formatResult(result);
const expression = formatter.formatExpression(operation, a, b, formattedResult);
this.history.push({
operation,
operands: [a, b],
result: formattedResult,
expression,
timestamp: new Date()
});
return formattedResult;
} catch (error) {
console.error('Calculation error:', error.message);
throw error;
}
}
getHistory() {
return this.history;
}
clearHistory() {
this.history = [];
}
}
export default Calculator;