What are JavaScript modules? How do you export and import them?

JavaScript modules are a way to organize and encapsulate code into reusable units. They allow you to break down your codebase into smaller, self-contained modules, each responsible for a specific functionality. Modules improve code maintainability, reusability, and enable better collaboration among developers.

JavaScript modules follow the ES modules (ESM) specification, which is supported by modern browsers and Node.js. The ESM syntax introduces two main concepts: exporting and importing.

Exporting from a Module:

To export values, functions, or objects from a module, you use the export keyword. There are multiple ways to export from a module:

Named Exports:

With named exports, you can export multiple values or functions from a module by explicitly specifying their names.

Example:

// module.js

export const PI = 3.14;

export function double(num) {

  return num * 2;

}

In this example, we export a constant PI and a function double() using the export keyword.

Default Export:

A module can have a single default export, which is typically used to export the primary functionality or main object from the module.

Example:

// module.js

export default function greet(name) {

  console.log(`Hello, ${name}!`);

}

Here, we export a default function greet(), which will be the main export of the module.

Combining Named and Default Exports:

It’s also possible to have a combination of named and default exports in a module.

Example:

// module.js

export const PI = 3.14;

export function double(num) {

  return num * 2;

}

export default function greet(name) {

  console.log(`Hello, ${name}!`);

}

In this case, we have both named exports (PI and double()) and a default export (greet()).

Importing from a Module:

To use the exported values from a module in another module, you need to import them. There are different ways to import from a module:

Named Imports:

With named imports, you can selectively import specific values or functions from a module.

Example:

// main.js

import { PI, double } from ‘./module.js’;

console.log(PI); // Output: 3.14

console.log(double(5)); // Output: 10

In this example, we import the named exports PI and double() from the module.js module.

Default Import:

When a module has a default export, you can import it using any name you prefer.

Example:

// main.js

import greet from ‘./module.js’;

greet(‘John’); // Output: Hello, John!

Here, we import the default export greet() from the module.js module and use it as greet(‘John’).

Combining Named and Default Imports:

You can combine named imports and a default import in a single import statement.

Example:

// main.js

import greet, { PI, double } from ‘./module.js’;

console.log(PI); // Output: 3.14

console.log(double(5)); // Output: 10

greet(‘John’); // Output: Hello, John!

In this case, we import the named exports PI and double() along with the default export greet() from the module.js module.

It’s worth noting that you can also use an alias when importing to avoid naming conflicts or provide a more meaningful name for the imported module or exports.

Example:

// main.js

import { PI as circlePI, double } from ‘./module.js’;

import greet from ‘./module.js’;

console.log(circlePI); // Output: 3.14

console.log(double(5)); // Output: 10

greet(‘John’); // Output: Hello, John!

In this example, we use the alias circlePI for the named export PI to avoid conflicts with other variables or constants in the main.js module.

JavaScript modules provide a clean and organized way to structure and share code across different files. They help prevent global namespace pollution, enable code encapsulation, and support code reuse. Modules are widely used in modern JavaScript development, both on the client-side and server-side, to create scalable and maintainable applications.