JavaScript Modules
As your JavaScript projects grow, you’ll want to organize your code into separate files. Modules let you split your code into reusable pieces that you can import and export between files. This keeps things clean and maintainable.
Why Use Modules?
Before modules, all JavaScript was in global scope, which could lead to naming conflicts. Modules solve this by:
- Keeping code organized in separate files
- Avoiding global namespace pollution
- Allowing selective importing of what you need
- Making code easier to maintain and debug
Exporting from a Module
To share code from a file, use export. There are named exports and default exports.
Named Exports
Export multiple things from a file:
// math.js
export function add(a, b) {
return a + b;
}
export function subtract(a, b) {
return a - b;
}
export const PI = 3.14159;Default Export
Export one main thing from a file:
// calculator.js
export default function calculate(operation, a, b) {
switch (operation) {
case 'add':
return a + b;
case 'subtract':
return a - b;
default:
return 0;
}
}You can also export variables, classes, etc. For classes, see JavaScript classes later.
Importing into a Module
Use import to bring exported code into another file.
Importing Named Exports
// main.js
import { add, subtract } from './math.js';
console.log(add(5, 3)); // Outputs: 8
console.log(subtract(10, 4)); // Outputs: 6
Import specific things or everything:
import * as MathUtils from './math.js';
console.log(MathUtils.add(5, 3));Importing Default Exports
import calculate from './calculator.js';
console.log(calculate('add', 5, 3)); // Outputs: 8
You can rename imports to avoid conflicts:
import { add as sum } from './math.js';
console.log(sum(5, 3)); // Outputs: 8
Module File Structure
Modules need to be loaded as modules. In HTML, use type="module":
<script type="module" src="main.js"></script>In Node.js, use .mjs extension or "type": "module" in package.json.
For browser compatibility, you might need a bundler like Webpack. Learn more about setting up modules in the MDN Modules guide.
Common Module Patterns
Utility Functions
Put helper functions in a utils module:
// utils.js
export function formatDate(date) {
return date.toLocaleDateString();
}
export function capitalize(str) {
return str.charAt(0).toUpperCase() + str.slice(1);
}// app.js
import { formatDate, capitalize } from './utils.js';
console.log(formatDate(new Date())); // Outputs: current date
console.log(capitalize('hello')); // Outputs: Hello
Configuration
Export config objects:
// config.js
export const API_URL = 'https://api.example.com';
export const TIMEOUT = 5000;import { API_URL } from './config.js';
fetch(API_URL + '/data');Dynamic Imports
For code you only need sometimes, use dynamic imports:
if (condition) {
import('./lazyModule.js').then(module => {
module.doSomething();
});
}This loads the module only when needed, improving initial load time.
Modules and Classes
Modules work great with classes:
// Person.js
export class Person {
constructor(name) {
this.name = name;
}
greet() {
console.log(`Hello, I'm ${this.name}`);
}
}import { Person } from './Person.js';
const john = new Person('John');
john.greet();Modules help you build larger applications. Start by organizing related functions into modules, and import what you need.
For more on modern JavaScript features including modules, check the ES6 features tutorial.
The MDN JavaScript Modules documentation has comprehensive examples.