Show TOC

Cyclic DependenciesLocate this document in the navigation structure

A workaround is used to void cyclic dependencies.

The functionality in two modules can be interdependent, for example, module A requires module B to execute, and module B requires module A. The function ensures that the execution of a calling module only continues when the required module has been loaded and executed. Consequently, cyclic dependencies cannot be resolved and would cause an endless series of requests (A->B->A->B->...).

To avoid this, use the following workaround: As soon as a module A has been loaded and is about to execute, it is regarded as declared. So, when this module A embeds another module B which has not been loaded, module B will be loaded and executed. If B now again requires A, then the dependency resolution runtime will find that A has been declared already (despite the fact that its execution has not been finished yet) and simply returns. This workaround helps to break the endless loop, but it doesn't re-ensure the original promise of

Cyclic modules have to deal with that gap on their own. There are several ways/best practices how to do this:

  • Variant 1: Merge A and B

    If the conflicts can not be resolved easily, or if the modules are so highly related that they will be used together most of the time, then merging them into one module is the simplest solution.

  • Variant 2: Interlaced Execution of A and B

    This variant makes use of the fact that the module loading takes place exactly at the source location where the function is executed. Let's assume that the content of modules A and B can be structured as follows:

    // Module A, Part A.1
        // Module Section A.1, does not depend on Module B and provides all code that module B depends on.
        // Module Section A.2, might depend on code in Module Section B.1
    // Module B, Part B.1
        // Module Section B.1, does not depend on Module A and provides all code that module A depends on.
        // Module Section B.2, might depend on code in Module Section A.1

    Further assume (WLOG) that module A is loaded first. Then section A.1 will be executed and will be available to the outside world before the require('B') is executed. During the require, the framework will detect that B is not available yet, will load and execute it. The execution starts with section B.1 which succeeds as it does not depend on A. When the execution of B reaches the require('A') statement, the framework detects that A has been loaded already and continues without loading A again. But remember, that the code from section A.2 is not available yet. The execution of B however continues and succeeds as - by assumption - B.2 does not depend on A.2. Now, the first require('B') succeeds and returns and section A.2 will be executed. And it might use the code from section B.1.

Procedure and result are similar in the case that B is loaded first.