Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Webpack ES6 modules circular dependencies when using index files

I have a big project, I try to refactor to ES6 modules right now.

To make further development easier, I wanted to introduce index files, which just export all modules within the directory:

index.js:

export { default as ModuleA } from './moduleA'
export { default as ModuleB } from './moduleB'
export { default as ModuleC } from './moduleC'

moduleA.js:

import { ModuleB } from './index'

moduleB.js:

import { ModuleC } from './index'

ModuleC.doSomething()

moduleC.js:

export default {
  doSomething: () => {}
}

Starting point is ModuleA.

The problem is, that in ModuleB ModuleC is undefined, so doSomething can't be executed.
I suspect some issues with circular dependencies, since moduleB tries to access the index again, which parses moduleB before moduleC.

Is it just not possible to do this, or is there another solution?

like image 703
tjwelde Avatar asked Mar 05 '18 18:03

tjwelde


People also ask

How do I fix circular dependencies?

To resolve circular dependencies: Then there are three strategies you can use: Look for small pieces of code that can be moved from one project to the other. Look for code that both libraries depend on and move that code into a new shared library. Combine projectA and projectB into one library.

How do I get rid of cyclic dependency in Java?

A simple way to break the cycle is by telling Spring to initialize one of the beans lazily. So, instead of fully initializing the bean, it will create a proxy to inject it into the other bean. The injected bean will only be fully created when it's first needed.

What is module circular dependency?

In software engineering, a circular dependency is a relation between two or more modules which either directly or indirectly depend on each other to function properly. Such modules are also known as mutually recursive.

How do I find circular dependency?

By running a cli command npx madge --circular --extensions ts ./ we can quickly get a list of circular dependencies of all . ts files in current directory and its subdirectories. That's it! Now you see where you have circular dependencies and can go and fix it.


2 Answers

The issue here is that ModuleC has not been exported by the time that ModuleB is exported and runs, and since ModuleC is a requirement of ModuleB, it can't run. If I were you, I would just export each of them from their own files, and when you import them, import them from their own files instead of index.js.

Example

ModuleA.js:

import { ModuleB } from 'moduleB.js'
    export default {
      // Your code here
}

ModuleB.js

import { ModuleC } from 'moduleC.js'
moduleC.doSomething();

ModuleC.js

export default {
    doSomething: () => {
      // Your code
    }
}

And finally, since ModuleA is the entry point from index.js, just import it into index.js and run what you need to run.

like image 71
Niall McQuay Avatar answered Sep 22 '22 01:09

Niall McQuay


Alright. Solved it.

The problem ist, that when ModuleB tries to import ModuleC from the index, the index will be parsed again and will see ModuleB before it can reach ModuleC.
It seems to work with only two modules, since the index file doesn't get reparsed, I think.

The solution:
Import modules, which try to load other modules from the index file at last.

So index.js should look like this:

export { default as ModuleA } from './moduleA'
export { default as ModuleC } from './moduleC'
export { default as ModuleB } from './moduleB'
like image 23
tjwelde Avatar answered Sep 22 '22 01:09

tjwelde