Javascript Es6 Modules And Import Export Complete Guide

 Last Update:2025-06-22T00:00:00     .NET School AI Teacher - SELECT ANY TEXT TO EXPLANATION.    8 mins read      Difficulty-Level: beginner

Understanding the Core Concepts of JavaScript ES6 Modules and Import Export

Understanding JavaScript ES6 Modules: Import & Export

Introduction to ES6 Modules

ES6 (ECMAScript 2015) introduced modules as a native way to share code between different JavaScript files. Prior to ES6, developers relied on external libraries like RequireJS or used global variables, both of which could lead to spaghetti code and management issues. ES6 modules bring clarity, maintainability, and encapsulation by allowing you to organize code into manageable and reusable pieces.

Exporting Code

To export a function, object, or primitive value from a module, you use export. There are two types of export statements:

  1. Named Exports: Multiple named exports per module are allowed and are useful for exporting several values.

    // math.js
    export const add = (a, b) => a + b;
    export const subtract = (a, b) => a - b;
    
  2. Default Exports: Only one default export per module. Useful when a module is meant to export a single value or object.

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

Importing Code

Correspondingly, the import statement is used to bring in values exported from other modules.

  1. Named Imports:

    • Importing named exports requires curly braces to specify the names.
    // main.js
    import { add, subtract } from './math.js';
    console.log(add(5, 3)); // Outputs: 8
    console.log(subtract(5, 3)); // Outputs: 2
    
  2. Default Imports:

    • You can import the default export without curly braces and optionally rename it.
    // main.js
    import add from './calculator.js';
    console.log(add(5, 3)); // Outputs: 8
    
  3. Mixing Named and Default Imports:

    import multiply, { add, subtract } from './mathUtils.js';
    

Re-exporting

You can also re-export named imports and exports from a module.

// advancedMath.js
export * from './math.js'; // re-exports all named exports from math.js
export { add as plus } from './math.js'; // re-exports named as an alias

Cycles in Module Dependencies

Circular dependencies occur when two or more modules depend on each other directly or indirectly. ES6 modules can detect and resolve these, provided proper handling.

Benefits of Using ES6 Modules

  1. Encapsulation: Encourages modular design by preventing pollution of the global namespace.
  2. Reusability: Easily share code across projects and applications.
  3. Lazy Loading: Supports dynamic imports (import()), which can delay loading modules until they are needed.
  4. Tree Shaking: During bundling, unused code is automatically eliminated, optimizing load times.

Syntax and Best Practices

  • Module File Extensions: While not strictly necessary, .js is commonly used. Some build tools prefer .mjs for better clarity.
  • Asynchronous Loading: Modules are fetched asynchronously, which is different from <script> tags used in HTML.
  • Strict Mode: Modules run in strict mode by default, which can catch certain syntax errors and enforce good practices.
  • Top-Level Await: ES2022 introduces top-level await allowing asynchronous initialization at the top level of modules. This makes async setup simpler than using IIFE (Immediately Invoked Function Expression).
  • File Paths: For imports, ensure correct paths. Use relative paths (./module.js) for modules in the same or subdirectory, and adjust accordingly for parent directories (../module.js).

Example Scenario

Consider a mathUtils.js file that exports various math operations:

// mathUtils.js
export const multiply = (a, b) => a * b;
export const divide = (a, b) => b !== 0 ? a / b : 'Cannot divide by zero!';
export default (a, b) => a + b; // Default export adds two numbers

In the main file, you can mix and match named and default imports:

Online Code run

🔔 Note: Select your programming language to check or run code at

💻 Run Code Compiler

Step-by-Step Guide: How to Implement JavaScript ES6 Modules and Import Export

Here’s a step-by-step example to help you understand how to use JavaScript ES6 modules, including import and export.


Step 1: Setting up the project

First, ensure that your development environment supports ES6 modules. Typically, this means using a modern browser (like Chrome, Firefox, Edge, or Safari) or a server environment with Node.js (with some setup).

For simplicity, let's demonstrate with a basic HTML setup using local files in a browser.

Directory Structure:

/example-project
|-- main.js
|-- utils.js
|-- index.html

Step 2: Writing the module (exporting)

Create a file named utils.js to define some utility functions and values. This file will export the functionality that we'll use in our main file.

// utils.js

// Function to add two numbers
export function add(a, b) {
    return a + b;
}

// Function to subtract two numbers
export function subtract(a, b) {
    return a - b;
}

// A constant to use
export const PI = 3.14159;

// Default export (you can have only one default export per module)
export default function greet(name) {
    console.log(`Hello, ${name}!`);
}

Breakdown:

  • export function add(a, b) and export function subtract(a, b): These lines are named exports. You can import them by their names in other files.
  • export const PI: This line is a constant export, also named.
  • export default function greet(name): This is a default export. When importing, you can give it any name you want.

Step 3: Importing the module

Now, create another file called main.js. This is the entry point of your application where you import the functions and values from utils.js and use them.

// main.js

// Importing named exports and the default export from utils.js
import { add, subtract, PI } from './utils.js';
import greet from './utils.js';

// Using the named exports
console.log(add(5, 3));       // Output: 8
console.log(subtract(10, 4)); // Output: 6
console.log(PI);             // Output: 3.14159

// Using the default export
greet('World');              // Output: Hello, World!

Breakdown:

  • import { add, subtract, PI } from './utils.js';: This line imports named exports from utils.js. Notice that the curly braces {} are used to import named exports.
  • import greet from './utils.js';: This line imports the default export from utils.js. Note that you can name the default export anything you like in the importing file.

Step 4: Setting up HTML to use these modules

Finally, you need to ensure that your HTML file can load the JavaScript modules. Create an index.html file to include your main.js file as a module.

<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>ES6 Modules Example</title>
</head>
<body>
  <h1>JavaScript ES6 Modules Example</h1>
  <script type="module" src="./main.js"></script>
</body>
</html>

Key Points:

  • type="module": This attribute is necessary when importing modules in the browser. It tells the browser to treat the file as an ES6 module.

Full Project Example

Here is the full project as described:

utils.js

export function add(a, b) {
    return a + b;
}

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

export const PI = 3.14159;

export default function greet(name) {
    console.log(`Hello, ${name}!`);
}

main.js

import { add, subtract, PI } from './utils.js';
import greet from './utils.js';

console.log(add(5, 3));
console.log(subtract(10, 4));
console.log(PI);
greet('World');

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>ES6 Modules Example</title>
</head>
<body>
  <h1>JavaScript ES6 Modules Example</h1>
  <script type="module" src="./main.js"></script>
</body>
</html>

Additional Notes

Named vs. Default Exports

  • Named Exports: You can have many named exports in a module. When importing, you need to use curly braces {} and include the exact name.

  • Default Exports: A module can have only one default export. You don’t need curly braces {} when importing the default export, but you can name it anything you want.

Mixing Named and Default Exports

// utils.js
export const HELLO_MESSAGE = 'Hello, World!';
export default function greet(name) {
    console.log(`Hello, ${name}!`);
}
// main.js
import greet, { HELLO_MESSAGE } from './utils.js';

console.log(HELLO_MESSAGE); // Output: Hello, World!
greet('World');             // Output: Hello, World!

Using Aliases

You can also use aliases (renaming imports) when importing to make your code more readable or avoid naming conflicts.

// main.js
import myGreet, { add as sum } from './utils.js';

console.log(sum(5, 3));      // Output: 8
myGreet('World');           // Output: Hello, World!

Importing All Named Exports

You can import all the named exports of a module into a single object using * as syntax.

// main.js
import * as utils from './utils.js';

console.log(utils.add(5, 3));    // Output: 8
console.log(utils.PI);          // Output: 3.14159
utils.greet('World');           // Output: Hello, World!

Conclusion

Using JavaScript ES6 modules makes your code more modular, maintainable, and reusable. This example demonstrated how to create, export, and import functions and values using named and default exports. By structuring your code with modules, you can better manage complex applications and avoid conflicts between different parts of your code.


Top 10 Interview Questions & Answers on JavaScript ES6 Modules and Import Export

1. What are JavaScript ES6 modules?

Answer: JavaScript ES6 (ECMAScript 2015) introduced a formal module system in the browser and Node.js, allowing developers to encapsulate code into separate modules that can be easily imported or exported. Modules help organize code, avoid naming collisions, and improve maintainability.

2. How do you create a JavaScript module?

Answer: A JS file becomes a module when it contains an import or export statement. The simplest way to create a module is by explicitly adding one of these statements. For example:

// mathModule.js
export const add = (a, b) => a + b;
export function multiply(a, b) {
    return a * b;
}

This file now exports two functions: add and multiply.

3. What is the difference between default export and named export?

Answer:

  • Named Export: Allows multiple values to be exported from a module using distinct names. Example:
// utils.js
export const pi = 3.14159;
export function square(x) { 
    return x * x; 
}

Importing:

import { pi, square } from './utils.js';
  • Default Export: Only one value can be exported from a module as a "default". When importing, you can choose any name for the variable. Example:
// calculator.js
const defaultFunction = () => { /*...*/ };
export default defaultFunction;

Importing:

import arbitraryName from './calculator.js';

4. How do you import a named export from a module?

Answer: To import named exports, use the curly braces {} around the exported variable(s). Example:

Exported Module:

// shapes.js
export const rectangleArea = (width, height) => width * height;
export const circleArea = (radius) => Math.PI * radius * radius;

Importing:

import { rectangleArea, circleArea } from './shapes.js';

5. Can you import both default and named exports at once?

Answer: Yes, you can import both a default export and any named exports from a module. Example:

Exported Module:

// tools.js
export default function defaultTool() { }
export const toolA = function() { };
export const toolB = function() { };

Importing both:

import defaultTool, { toolA, toolB } from './tools.js';

6. How do you rename an import in JavaScript?

Answer: You can rename named imports using the as keyword. This is useful when you want to avoid a name conflict or when you prefer a shorter name. Example:

Exported Module:

// constants.js
export const magicNumber = 7;

Renaming on import:

import { magicNumber as mNum } from './constants.js';
console.log(mNum); // Outputs 7

7. Can you import all named exports from a module at once?

Answer: Yes, you can use the * symbol in combination with the as keyword to import all exported entities from a module into an object.

import * as shapes from './shapes.js';
console.log(shapes.rectangleArea(3, 5)); // Usage
console.log(shapes.circleArea(4));       // Usage

8. How do you handle circular dependencies in JavaScript ES6 modules?

Answer: Circular dependencies occur when module A depends on B, and B depends back on A. JavaScript ES6 modules have built-in handling for circular dependencies during static analysis and linking but can lead to undefined behavior if not carefully managed.

One strategy to mitigate this issue is to restructure your code to break dependency cycles. Another method involves using a lazy import (i.e., import() syntax) within functions to defer loading the modules until they're actually needed.

9. What are the benefits of using ES6 modules over script tags?

Answer: Using ES6 modules provides several benefits:

  • Scope Encapsulation: Variables defined within a module are scoped to that module and not leaked to the global namespace.
  • Performance Optimization: Dynamic loading of modules allows browsers to only load and execute the necessary scripts, improving performance.
  • Version Management: Modules can support different versions of the same library by being imported from different paths.
  • Built-in Support for Asynchronous Loading: Modern browsers and tools like Webpack natively support async loading of modules.

10. Does Node.js use ES6 modules by default?

Answer: Starting from Node.js v12.x, ES6 modules became available behind the flag --experimental-modules. From version 14.x LTS, ES6 modules were officially supported without the need for experimental flags. However, the traditional CommonJS modules (require) remain the default format in Node.js.

For ES6 modules to work in Node.js, your script needs to be run with the .mjs extension or your package.json should include "type": "module". For example:

{
  "type": "module"
}

Or use the .mjs extension:

You May Like This Related .NET Topic

Login to post a comment.