TypeScript 和 systemjs 循环依赖

TypeScript and systemjs circle dependency

我对模块的循环依赖有问题:

even.ts

import { Odd } from './odd';

export class Even {

    log(){
        return console.log(Odd);        
    }  
}

odd.ts

import { Even } from './even';

export class Odd extends Even{

  log(){
        return console.log(Even);       
    }  

}

配置:

System.config({
  defaultJSExtensions: true,
  baseURL: '/',
  transpiler: 'typescript'
});

System.import('even.js').then( a => console.log(a));

我尝试使用 requre.js 但它无法解决循环依赖关系。在 systemjs 文档中 is written that it can resolve circle depedencies 但它不起作用。 __extends 函数中的 Cannot read property 'prototype' of undefined 例外。

也许使用 CommonJS 更好,但据我所知,我不能像在 AMD 和 SystemJS 中那样使用根目录中的模块路径。

解决这个问题的最简单方法是更多地考虑模块,而不是遵循 C# 或 Java 中的模式(每个文件有一个 class)。

如果您的 OddEven class 有着千丝万缕的联系,请将它们放在同一个模块(文件)中。在您描述的设置中,您不能在没有另一个的情况下使用一个,所以为什么要强制第二个 HTTP 请求。

或者,重新访问您的继承层次结构...也许您选择了错误的基 class 如果基 class 需要了解其特化之一。也许你错过了 OddEven 都应该扩展的真正基础 class,或者你可以共享一个接口而不是基础 class.

另一种可能性是在这种情况下您应该使用委托而不是继承,或者您应该从工厂请求实例。

虽然循环依赖管理听起来是个不错的功能,但您始终可以通过回到 OOD 和 SOLID 原则来解决没有它的问题。

如果您只需要修复它,那么就做

System.import('./odd') .then(() => System.import('./even')) .then(a => console.log(a));

会起作用。

问题发生在同时使用 TypeScript 和 Babel 的情况下,似乎是由于它们在 ES5 中实现 class 继承的方式所致(通过转译代码中的 _extends 和 _inherits 方法)。这些方法依赖于包含 superclass 的模块已被完全执行,但是 SystemJS 不知道这一点,因此它没有以正确的顺序执行模块。