Skip to content Skip to sidebar Skip to footer

Es6 Modules And Circular Dependency

I'm having this problem in ES6 in a Babel Environment: // A.js class A { } export default new A(); // B.js import C from './C'; class B { } export default new B(); // C.js import

Solution 1:

What's the best practice about circular dependencies in ES6?

Avoid them altogether. If you cannot (or don't want to) completely avoid them, restrict the involved modules to only use function declarations with circular dependencies, never initialise top-level values (constants, variables, classes) by using imported values (that includes extends references).

What would possibly work in different environments (Babel, Rollup)?

The order of module resolution and initialisation is defined in the ES6 specification, so this should be the same in all ES6 environments - regardless how the modules are loaded and how their identifiers are resolved.

How to solve this kind of circular dependencies setup?

If you do have a circular dependency X -> Y -> Z -> … -> X -> …, you need to establish a start point. Say you want X to be loaded first, although it depends on Y, so you need to make sure that X never uses any of the imported values until all modules in the circle are completely initialised. So you break the circle between X and Y, and you will need to start the import chain at Y - it will recursively traverse the dependencies until it stops at X, which has no further dependencies that are not already getting initialised, so it will be the first module to be evaluated.

The rule you have to follow then is to always import Y before importing any of the other modules in the circle. If you even once do not use this common single entry point to the circle, your house of cards will collapse.

In your particular example, this means that index.js will need to use

import A from'./A';
import C from'./C'; // entry point to circular dependenciesimport B from'./B';
…

Post a Comment for "Es6 Modules And Circular Dependency"