Skip to main content

Command Palette

Search for a command to run...

JavaScript Modules

Import and Export Explained

Updated
•6 min read•View as Markdown
JavaScript Modules
S
Software Developer | Full Stack Developer |

Introduction

As our application grows bigger, we want to split it into multiple files, so called “modules”. A module may contain a class or a library of functions for a specific purpose.

For a long time, JavaScript existed without a language-level module syntax. That wasn’t a problem, because initially scripts were small and simple, so there was no need.

But eventually scripts became more and more complex, so the community invented a variety of ways to organize code into modules, special libraries to load modules on demand.

To name some (for historical reasons):

  • AMD – one of the most ancient module systems, initially implemented by the library require.js.

  • CommonJS – the module system created for Node.js server.

  • UMD – one more module system, suggested as a universal one, compatible with AMD and CommonJS.

What is a module?

A module is just a file. One script is one module. As simple as that.

Modules can load each other and use special directives export and import to interchange functionality, call functions of one module from another one:

  • export keyword labels variables and functions that should be accessible from outside the current module.

  • import allows the import of functionality from other modules.

Exporting functions or values:

The export declaration is used to export values from a JavaScript module. Exported values can then be imported into other programs with the import declaration or dynamic import. The value of an imported binding is subject to change in the module that exports it — when a module updates the value of a binding that it exports, the update will be visible in its imported value.

// Exporting functions from greet.js file
export function greet(name) {
  console.log("Hello World!", name);
}

// Exporting values
export const name = "Alice";

Importing modules:

The static import declaration is used to import read-only live bindings which are exported by another module. The imported bindings are called live bindings because they are updated by the module that exported the binding, but cannot be re-assigned by the importing module.

// import greet function from greet.js file
import { greet, name } from "./greet.js";

greet(name);

What is the Default Export in JavaScript?

In JavaScript, a default export is a way to share a single value, function, or class as the main thing from a file with other parts of your code.

When you have a file that needs to be used in other parts of your application, you can mark one item in that file as the default export using the export default syntax.

This means that when you import from that file in another part of your code, you don't need to use curly braces {} around the import statement. Instead, you can give it any name you want during the import, making it more convenient to use.

// 📂 math.js
const add = (a, b) => a + b;
export default add;

// 📂 main.js
import myAddFunction from './math.js';
const result = myAddFunction(5, 10); // This will call the add function from math.js and store the result in the 'result' variable.

What is the Named Export in JavaScript?

Named exports in JavaScript allow you to export multiple functions, variables, or classes from a single file as separate entities. Instead of exporting everything as a single unit, you can specifically name and export each part individually.

This gives you more control over what parts of the code you want to share with other modules. When importing these named exports into other files, you have to use the exact names that were used during the export, ensuring that you can access and use the specific functionalities you need from the source file.

// 📂 math.js
export function add(a, b) {
  return a + b;
}

export function subtract(a, b) {
  return a - b;
}

// 📂 main.js
import { add, subtract } from './math.js';

const result1 = add(5, 3); // result1 will be 8
const result2 = subtract(10, 4); // result2 will be 6

In JavaScript, a file can have only one default export, but it can have multiple named exports as needed.

Let's take a look at the differences between named exports and default exports:

Named Exports vs Default Exports:

A few characteristics of named exports are the following:

  • When you use named exports, you can export multiple values, functions, or classes from a single file, giving each of them a specific name.

  • You need to wrap the items you want to export in curly braces {} when importing them in another file, and you must use the exact names used during the export.

  • Named exports are great when you want to share multiple things from a file and give them distinct names to use in other parts of your code.

  • A file can have as many named exports as you like.

A few characteristics of default exports are the following:

  • Default exports are useful when you want to export only one main thing from a file. It is like marking that one thing as the most important to share.

  • When importing a default export in another file, you can give it any name you want during the import, and you don't need to use curly braces {}.

  • A file can have only one default export.

Benefits of Modular Code:

Modular code enhances software development by improving readability and maintainability, as breaking large programs into smaller, self-contained units makes the codebase easier to understand, navigate, and update without affecting unrelated sections.

Key benefits include:

  • Reusability: Modules can be reused across different parts of an application or in entirely new projects, reducing development time and ensuring consistency.

  • Easier Debugging and Testing: Issues can be isolated to specific modules, allowing for more efficient testing and faster error correction.

  • Parallel Development: Multiple developers or teams can work on different modules simultaneously, speeding up the overall development process.

  • Scalability: New features can be added by integrating additional modules without disrupting the existing system structure.

  • Enhanced Reliability: Well-organized, modular code reduces the risk of cascading errors and makes the software more robust over time.

Conclusion:

In conclusion, JavaScript exports offer powerful tools for managing code organization and sharing functionalities between different parts of our applications.

We explored the differences between named exports, allowing multiple entities to be exported from a file with specific names, and default exports, marking one primary entity as the main export. Both mechanisms are essential in promoting modularity and code reusability.

By understanding these export techniques, you can create more organized and efficient code structures, resulting in better scalability in your JavaScript projects.