es6 依赖循环_ES6模块和循环依赖

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 A from './A';

import B from './B';

class C {

constructor(A, B){

this.A = A;

this.B = B; // undefined

}

}

export default new C(A, B)

I import them like this:

// stores/index.js

import A from './A';

import B from './B';

import C from './C';

export {

A,

B,

C

}

And from my app entry point I do:

import * as stores from './stores';

I would (hoped) expected the order of execution to be A -> B ->C but in reality it is A-> C-> B.

This is due to module B importing C, so that the C module is evaluated before the B module. This creates a problem in the setup of C because in that case B would be undefined.

I've seen a similar question but I'm not sure the init function is the best solution here, it seems a bit hacky.

Q: What's the best practise about solving this kind of circular dependencies in ES6 that would possibly work in different environments (Babel, Rollup)?

解决方案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 dependencies

import B from './B';

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值