w3resource

Handle Circular dependencies in JavaScript Modules


Circular Dependency:

Write a JavaScript program to create two modules that import each other and handle the circular dependency.

A circular dependency occurs when two or more modules depend on each other. Proper handling of circular dependencies is crucial to avoid runtime errors or unexpected behaviour.

Solution 1: Breaking Circular Dependency Using a Shared Module

Code:

File: moduleA.js

This module depends on a shared module and uses functions indirectly.

// moduleA.js
 // Importing the shared module
import { sharedFunction } from './shared.js';

// Defining a function and exporting it
export function functionA() {
  console.log('Function A in Module A');
  sharedFunction('from Module A');
}

File: moduleB.js

This module also depends on the shared module.

// moduleB.js
// Importing the shared module
import { sharedFunction } from './shared.js';

// Defining a function and exporting it
export function functionB() {
  console.log('Function B in Module B');
  sharedFunction('from Module B');
}

File: shared.js

This shared module is used to decouple the circular dependency.

// shared.js
// Shared function to handle indirect communication
export function sharedFunction(message) {
  console.log('Shared function called ${message}');
}

File: main.js

This file demonstrates the usage of the modules.

// main.js  
// Importing functions from both modules
import { functionA } from './moduleA.js';
import { functionB } from './moduleB.js';

// Calling the functions
functionA(); // Logs "Function A in Module A" and "Shared function called from Module A"
functionB(); // Logs "Function B in Module B" and "Shared function called from Module B"

Output:

Function A in Module A
Shared function called from Module A
Function B in Module B
Shared function called from Module B

Explanation:

  • Modules moduleA.js and moduleB.js both rely on shared.js to avoid direct dependence on each other.
  • The shared.js module acts as an intermediary for shared functionality.
  • This approach breaks the circular dependency by introducing a shared abstraction layer.

Solution-2: Delayed Imports Using Functions

Code:

File: moduleA.js

This module exports a function that depends on moduleB.js.

// moduleA.js
 // Defining and exporting a function that requires delayed access
export function functionA() {
  console.log('Function A in Module A');
  const { functionB } = require('./moduleB.js'); // Importing within the function
  functionB(); // Calling functionB dynamically
}

File: moduleB.js

This module exports a function that depends on moduleA.js.

// moduleB.js
// Defining and exporting a function that requires delayed access
export function functionB() {
  console.log('Function B in Module B');
  const { functionA } = require('./moduleA.js'); // Importing within the function
  functionA(); // Calling functionA dynamically
}  

File: main.js

This file demonstrates the usage of the modules.

// main.js  
// Importing functions from both modules
import { functionA } from './moduleA.js';
import { functionB } from './moduleB.js';

// Calling the functions
functionA(); // Logs both function outputs dynamically
functionB(); // Logs both function outputs dynamically

Output:

Function A in Module A
Function B in Module B
Function A in Module A
Function B in Module B
Function A in Module A
. . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . 

Explanation:

  • Modules moduleA.js and moduleB.js import each other only when their functions are called.
  • This delayed import mechanism avoids circular dependency issues by deferring execution.
  • This approach works well when functions are used dynamically rather than during module initialization.

Improve this sample solution and post your code through Disqus

Previous: JavaScript Modules using Namespace Imports.
Next: Export JavaScript Functions Inline for Modular Code.

What is the difficulty level of this exercise?

Test your Programming skills with w3resource's quiz.



Follow us on Facebook and Twitter for latest update.