Angular: 7.2.1 ES6 class ReferenceError : Cannot access 'X' before initialization

Angular: 7.2.1 ES6 class ReferenceError : Cannot access 'X' before initialization

我有以下 TypeScript class

export class Vehicule extends TrackableEntity {
  vehiculeId: number;
  constructor() {
    super();
    return super.proxify(this);
  }
}

我在 tsconfig.json 中的打字稿目标配置为 es6:

"compilerOptions": {
    "module": "es2015",
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "target": "es6",
}

在运行时,在 Chrome 处,代码失败:

ReferenceError: Cannot access 'Vehicule' before initialization
    at Module.Vehicule (https://localhost:44338/src-app-components-dispositifsDATI-dispositifsDATI-module.js:10559:100)
    at Module../src/app/domain/models/VehiculeGpsBoxInfo.ts (https://localhost:44338/src-app-components-dispositifsDATI-dispositifsDATI-module.js:11156:69)
    at __webpack_require__ (https://localhost:44338/runtime.js:84:30)
    at Module../src/app/domain/models/Vehicule.ts (https://localhost:44338/src-app-components-dispositifsDATI-dispositifsDATI-module.js:10571:78)
    at __webpack_require__ (https://localhost:44338/runtime.js:84:30)
    at Module../src/app/components/dispositifsDATI/mainDATI/listDATI/listDATI.component.ts (https://localhost:44338/src-app-components-dispositifsDATI-dispositifsDATI-module.js:6447:82)
    at __webpack_require__ (https://localhost:44338/runtime.js:84:30)
    at Module../src/app/components/dispositifsDATI/index.ts (https://localhost:44338/src-app-components-dispositifsDATI-dispositifsDATI-module.js:3053:95)
    at __webpack_require__ (https://localhost:44338/runtime.js:84:30)
    at Module../src/app/components/dispositifsDATI/dispositifsDATI.routes.ts (https://localhost:44338/src-app-components-dispositifsDATI-dispositifsDATI-module.js:2982:64)

我需要将 es5 更改为 es6 才能解决


编辑: VehiculeGpsBoxInfo.ts 文件正在像这样导入 Vehicule:

import { Vehicule } from "./Vehicule";

编辑 2:我想说这可能与 webpack 相关,模块在生成的模块中 exported/imported 的方式。

编辑 3:经过进一步研究,这似乎与上面显示的代码无关。开始了关于 .

的新问题

这是有道理的,您在构造函数 return super.proxify(this); 中将本地对象 (Vehicle) 传递给父对象 class。

注意本地Vehicle实例还没有被实例化(构造块还没有完成),所以你不能同时使用这个对象,你需要等待构造函数完成它的工作。

您可能 运行 遇到了这个 Angular 问题:https://github.com/angular/angular-cli/issues/15077

来自那一期:

Hi, is there a reason why you need emitDecoratorMetadata to be true?

This TypeScript option has a fundamental design limitation with ES2015+ code and is best avoided when targeting such output. As such this is an issue with TypeScript itself and not Angular.

Angular 8+ no longer requires the option. It was also previously only required for JIT mode which is typically only used in development.

解决方案是在 tsconfig.json 文件中设置 "emitDecoratorMetadata": false

旁注: 我必须说,鉴于以前版本的 Angular CLI 会自动添加 emitDecoratorMetadata: true,我没有理由明白为什么开发人员现在应该知道 emitDecoratorMetadata false,Angular 团队基本上说“这不是我们的问题”并且不采取任何行动就关闭了这个问题,这真是太可怕了。这可以通过添加一些更好的文档轻松地“修复”(正如有人在链接问题中指出的那样)。

请注意,在同一 .ts 文件中定义两个 public @Injectable 类 也可能导致此错误。

当我只是在本地制作原型时(尤其是在将一项服务重构为多项服务时),我不止一次被这个绊倒。

设置emitDecoratorMetadata: false也确实解决了这个问题;但如果您急于修复某些东西或不想在大型项目中使用 tsconfig.json 文件 fiddle - 了解您也许可以通过移动来修复它是很有用的类 之一到新文件中。

在 Angular 8 中,将 entryComponents 声明为 SharedModule 中的空列表对我造成了这个问题:

entryComponents: []

删除 entryComponents 后,一切正常。

由于循环依赖,我收到了这个错误,比如

  • A注入B
  • B注入C
  • C 注入 A

删除循环依赖修复了这个错误。

由于模块中导入语句的顺序,我运行进入了这个。必须在导入组件之前导入也访问该组件的文件。

循环依赖是魔鬼!

它导致编译器无法解析整个依赖循环。在大多数情况下,错误看起来像是您根本没有导入 classes。

有些人可能认为只应在服务和模块中防止循环依赖,但是,应在所有形式中防止循环依赖,即使在模型、组件和 classes 中也是如此。

当你有循环依赖时,这表明你(迟早)需要重构你的代码。以下提示可能对此很有用。假设我们要去除两个 classes A, B.

之间的循环依赖

方案一:Union/Merge

A 和 B 遵循完全相同的概念,它们可以合并为一个 class。

方案二:Separation/Creation

应该有一个新的 class C,A 和 B 都依赖或介于两者之间。

根据我的经验,在大多数情况下,循环依赖的发生是因为开发者倾向于将n个逻辑合并成k(k