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.

Last updated on