ES6模块和循环依赖 [英] ES6 Modules and Circular Dependency

查看:739
本文介绍了ES6模块和循环依赖的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Babel环境中的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)

我这样导入它们:

// 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'; 

我希望(执行)执行顺序为A-> B-> C,但实际上是A-> C->B.
这是由于模块B导入了C,因此在B模块之前先评估C模块.这会在C的设置中造成问题,因为在这种情况下 B 未定义的.

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.

我见过类似的问题,但我'不确定init函数是否是此处的最佳解决方案,似乎有点黑.

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 :解决ES6中这种可能在不同环境(Babel,汇总)中使用的循环依赖关系的最佳实践是什么?

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

推荐答案

ES6中关于循环依赖关系的最佳实践是什么?

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

完全避免使用它们.如果您不能(或不想)完全避免使用它们,请将涉及的模块限制为仅使用带有循环依赖项的函数声明,而不要使用来初始化顶级值(常量,变量,类)导入的值(包括extends引用).

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).

在不同的环境(Babel,汇总)中可能会起作用吗?

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

ES6规范中定义了模块解析和初始化的顺序,因此在所有ES6环境中都应该相同-不管如何加载模块以及如何解析其标识符.

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?

如果确实具有循环依赖项X -> Y -> Z -> … -> X -> …,则需要建立起点.假设您要先加载X,尽管它取决于Y,所以您需要确保X在圆形中的所有模块都完全初始化之前,永远不要使用任何导入的值.因此,您打破了XY之间的圈,您将需要在Y处启动导入链-它会递归地遍历依赖项,直到在X处停止为止,该依赖项不再存在其他依赖项已经初始化,因此它将是第一个要评估的模块.

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.

在您的特定示例中,这意味着index.js将需要使用

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';
…

这篇关于ES6模块和循环依赖的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆