Typescript SystemJS中的类型脚本继承和循环依赖
在一个非常大的项目中,我将TypeScript与模块系统(SystemJS)一起使用。SystemJS支持循环依赖关系,大多数情况下它工作正常。然而,当涉及到类型脚本继承时,事情就开始破裂了 例如,如果Typescript SystemJS中的类型脚本继承和循环依赖,typescript,ecmascript-6,circular-dependency,systemjs,es6-module-loader,Typescript,Ecmascript 6,Circular Dependency,Systemjs,Es6 Module Loader,在一个非常大的项目中,我将TypeScript与模块系统(SystemJS)一起使用。SystemJS支持循环依赖关系,大多数情况下它工作正常。然而,当涉及到类型脚本继承时,事情就开始破裂了 例如,如果a类依赖于B类,并且B类继承自a类,那么如果a类首先被加载: 它将暂停A类解析,并尝试加载B类依赖项 class B会认为它的依赖关系已经解决,因为已经触及了class A 类B的继承将无法解析,因为类A仍然未定义 我可以在web上找到的关于模块加载器循环依赖关系的大多数“解决方案”是: 将设计
a类
依赖于B类
,并且B类
继承自a类
,那么如果a类
首先被加载:
A类
解析,并尝试加载B类
依赖项class B
会认为它的依赖关系已经解决,因为已经触及了class A
类B的继承将无法解析,因为类A仍然未定义
- 将设计/组合类更改为单个模块
- CommonJS和非类型脚本特定的解决方法
有什么解决实际问题的办法吗 更改您的设计是最有利的解决方案。类不应该依赖于它的子类。如果您在工厂中使用它们,这是一个单独的问题,应该放在单独的类/函数/模块中 有什么解决实际问题的办法吗
正如您所说,只有在模块A首先加载时才会出现问题。解决方案是防止这种情况,并编写一个额外的模块,作为a及其所有子类的代理,同时以正确的顺序导入它们。在这种情况下,我建议您通过创建一个单独的接口
I
来删除a->B
的依赖关系。A
和B
都需要知道I
,而B
需要实现它
在加载过程中,B
必须告诉A
在哪里可以找到I
的构造函数或工厂(由B
实现)。这将留给您以下依赖项:
A -> I
B -> I
B -> A
接口I
可能如下所示:
interface I {
bFoo(): void;
}
export default I;
import I from "./i";
class A {
private static __ICtor : new() => I;
public static setIConstructor(ctor: new() => I) {
A.__ICtor = ctor;
}
private __atSomePoint() : I {
return new A.__ICtor();
}
}
export default A;
A类
可能如下所示:
interface I {
bFoo(): void;
}
export default I;
import I from "./i";
class A {
private static __ICtor : new() => I;
public static setIConstructor(ctor: new() => I) {
A.__ICtor = ctor;
}
private __atSomePoint() : I {
return new A.__ICtor();
}
}
export default A;
最后是B类:
import I from "./i";
import A from "./a";
class B extends A implements I {
public bFoo() {}
}
A.setIConstructor(B);
我想这会解决你的循环依赖,即使现在已经太晚了。这里有一个简单的方法可以通过使用Babel transform插件来解决这个问题: 它所做的是将文件开始时的模块导入转换为内联要求,即仅在使用其他模块之前实际导入/需要其他模块 在大多数情况下,这会自动解决问题,因为当任何使用代码的类实际运行时,模块都已完成导出
请注意,默认情况下,上面的插件应用于项目中的所有导入,将它们全部转换为内联。然而,一个更严重的问题是,我找不到一种内置的方法使它能够与相对路径导入/需求一起工作 我在这里的项目分支中解决了这两个问题: 我提出了这些更改的请求,但它正在等待审查