エラー百科辞典

Import Cycle Detected

コンポーネント、ディレクティブ、またはパイプが、このコンポーネントによって参照されている場合、コンパイラはインポートを追加する必要があり、インポートの循環が発生します。 たとえば、ParentComponentがテンプレートでChildComponentを参照しているシナリオを考えてみます。

parent.component.ts

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

child.component.ts

      
import {Component} from '@angular/core';import {ParentComponent} from './parent.component';@Component({  standalone: true,  selector: 'app-child',  template: 'The child!',})export class ChildComponent {  constructor(private parent: ParentComponent) {}}

ChildComponentはコンストラクタでParentComponentを参照しているため、child.component.tsからparent.component.tsへのインポートがすでに存在しています。

HELPFUL: 親コンポーネントのテンプレートには<child></child>が含まれています。 このテンプレートの生成されたコードには、ChildComponentクラスへの参照を含める必要があります。 この参照を行うために、コンパイラはparent.component.tsからchild.component.tsへのインポートを追加する必要があり、これがインポートの循環の原因となります。

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

リモートスコープ

NgModuleを使用している場合、循環を作成するインポートを追加しないように、依存関係を接続するコンポーネントが宣言されているNgModuleクラスにコードが追加されます。

これは「リモートスコープ」と呼ばれます。

ライブラリ

残念ながら、「リモートスコープ」コードは副作用があるため、ツリーシェイクが不可能になり、ライブラリでは使用できません。 そのため、"compilationMode": "partial"設定を使用してライブラリをビルドする場合、循環インポートを必要とするコンポーネントは、このNG3003コンパイラエラーが発生します。

エラーのデバッグ

生成される循環は、エラーメッセージの一部として表示されます。 たとえば、

      
コンポーネントChildComponentはテンプレートで使用されていますが、インポートすると循環が発生します。/parent.component.ts -> /child.component.ts -> /parent.component.ts

これを使用して、参照されたコンポーネント、パイプ、またはディレクティブがコンパイルされているコンポーネントにどのように依存しているかを特定します。 問題を解決するためのアイデアをいくつかご紹介します。

  • 循環を回避するために、依存関係を再配置してみてください。 たとえば、循環を発生させることなく、両方の依存ファイルにインポートできる独立したファイルに格納されている中間インターフェースを使用します。
  • 互いに参照しているクラスを同じファイルに移動して、それらの間でインポートを回避します。
  • インポートされた宣言がタイプとしてのみ使用される場合、インポートステートメントをタイプのみのインポート(import type構文を使用)に変換します。タイプのみのインポートは循環に寄与しません。