填写这份《一分钟调查》,帮我们(开发组)做得更好!去填写Home

NG3003: Import cycles would need to be created to compile this component
编译此组件时需要创建循环导入

说明

Description

该组件引用的组件、指令或管道将要求编译器添加某个导入,而这将导致循环导入。例如,考虑一个场景,其中 ParentComponent 在其模板中引用了 ChildComponent

A component, directive or pipe that is referenced by this component would require the compiler to add an import that would lead to a cycle of imports. For example, consider a scenario where a ParentComponent references a ChildComponent in its template:

parent.component.ts
      
      import { Component } from '@angular/core';

@Component({selector: 'app-parent', template: '<app-child></app-child>'})
export class ParentComponent {}
    
child.component.ts
      
      import { Component } from '@angular/core';
import { ParentComponent } from './parent.component';

@Component({selector: 'app-child', template: 'The child!'})
export class ChildComponent {
  constructor(private parent: ParentComponent) {}
}
    

由于 ChildComponent 在其构造函数中引用了 ParentComponent ,因此已经有一个从 child.component.tsparent.component.ts 的导入。

There is already an import from child.component.ts to parent.component.ts since the ChildComponent references the ParentComponent in its constructor.

但是请注意,父组件的模板中包含 <child></child>。因此,该模板的生成后代码必须包含对 ChildComponent 类的引用。而为了进行此引用,编译器必须将从 parent.component.ts 的导入添加到 child.component.ts ,这将导致循环导入:

But note that the parent component's template contains <child></child>. The generated code for this template must therefore contain a reference to the ChildComponent class. In order to make this reference the compiler would have to add an import from parent.component.ts to child.component.ts, which would cause an import cycle:

      
      parent.component.ts -> child.component.ts -> parent.component.ts
    

远程作用域

Remote Scoping

为了避免添加会导致循环的导入,可以将一些额外代码添加到 NgModule 类中,在该类中声明联系依赖关系的组件。这称为“远程作用域”。

To avoid adding imports that create cycles, additional code is added to the NgModule class where the component is declared that wires up the dependencies. This is known as "remote scoping".

Libraries

不幸的是,“远程作用域”代码有副作用,它会阻止摇树优化,并且不能在库中使用。因此,当使用 "compilationMode": "partial" 设置来构建库时,任何需要循环导入的组件都将引发此 NG3003 编译器错误。

Unfortunately, "remote scoping" code is side-effectful, which prevents tree shaking, and cannot be used in libraries. So when building libraries using the "compilationMode": "partial" setting, any component that would require a cyclic import will cause this NG3003 compiler error to be raised.


如何排除本错误

Debugging the error

这种循环会显示为错误消息的一部分。例如:

The cycle that would be generated is shown as part of the error message. For example:

      
      The component ChildComponent is used in the template but importing it would create a cycle:
/parent.component.ts -> /child.component.ts -> /parent.component.ts
    

使用它来确定所引用的组件、管道或指令是如何反向依赖要编译的组件的。以下是一些解决问题的方法:

Use this to identify how the referenced component, pipe or directive has a dependency back to the component being compiled. Here are some ideas for fixing the problem:

  • 尝试重新安排你的依赖关系,以避免循环。例如,使用存储在独立文件中的中间接口,可以将该文件导入两个相关文件中而不会导致循环导入。

    Try to re-arrange your dependencies to avoid the cycle. For example using an intermediate interface that is stored in an independent file that can be imported to both dependent files without causing an import cycle.

  • 将相互引用的类移到同一文件中,以避免它们之间的任何导入。

    Move the classes that reference each other into the same file, to avoid any imports between them.