reference-core について
Angular の `packages/core` を扱う開発者向けに、ランタイムアーキテクチャを解説するリファレンススキルです。レンダリング、依存性注入、変更検知、リアクティビティを説明し、コアコードの変更方法も示します。
主な機能
- 01Ivy の命令ベースレンダリング
- 02LView と TView のメモリモデル
- 03階層型依存性注入
- 04変更検知と Signals
- 05コアコードとテストの指針
活用シーン
- 01テンプレートから DOM 更新までの追跡
- 02インジェクターの解決方法の把握
- 03LView や TView の変更影響の評価
- 04コア実装とテストの検索
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ angular/ angular --skill reference-coreインストール後、Claude Code で/reference-coreを入力して読み込まれたか確認します。
詳細
Angular コア(packages/core)のメンタルモデル
このドキュメントでは、Angular フレームワークの中核である packages/core のアーキテクチャとメンタルモデルについて説明します。
1. 高レベルのアーキテクチャ
packages/core には、Angular の実行時ロジックが含まれています。主な役割は次のとおりです。
- レンダリング(Ivy/Render3):テンプレートを DOM の更新に変換します。
- 依存性注入(DI):オブジェクトの生成とライフタイムを管理します。
- 変更検知:モデルとビューを同期します。
- リアクティビティ:Signals と Zone.js の統合を担います。
2. レンダリングエンジン(Ivy / Render3)
レンダリングエンジン(packages/core/src/render3 にあります)は、命令ベースのアプローチを使用します。
主な概念
-
命令:Angular コンパイラーはテンプレートを一連の命令呼び出し(例:
ɵɵelementStart、ɵɵtext、ɵɵproperty)に変換します。これらの命令は実行時に実行され、ビューの作成と更新を行います。- 場所:
packages/core/src/render3/instructions
- 場所:
-
LView(論理ビュー):特定のビューインスタンスの_状態_を含む配列です。次の情報が格納されます。
- DOM ノード(
RElement、RText)。 - バインディング値(変更検知用)。
- ディレクティブ/コンポーネントのインスタンス。
- コンテキスト:
packages/core/src/render3/interfaces/view.ts
- DOM ノード(
-
TView(テンプレートビュー):ビューの_静的な構造_を記述するオブジェクトです。対応する配列は
TView.dataです。同じコンポーネント/テンプレートのすべてのインスタンス(LView)で共有されます。次の情報が格納されます。- バインディングのプロパティ名。
- ノードの関係情報。
- コンパイル済みのディレクティブ定義。
- コンテキスト:
packages/core/src/render3/interfaces/view.ts
-
メモリレイアウト:
LViewとTView.dataは並行する配列です。LViewのインデックスiは、TView.dataのインデックスiにあるメタデータに対応します。HEADER:固定サイズで、コンテキスト(Parent、Host など)を含みます。DECLS:静的ノード(要素、テキスト、パイプ)。VARS:バインディング値。EXPANDO:動的データ(ホストバインディング、インジェクター)。
レンダリングサイクル
- 作成モード:命令が DOM ノードを作成し、
LViewに格納します。 - 更新モード:命令が現在の値を、
LViewに格納された前回の値と比較します。値が変わっていれば、DOM を更新します。
3. 依存性注入(DI)
Angular の DI は階層構造になっており、相互に連携する 2 つのシステムに分かれています。
モジュールインジェクター(R3Injector)
@NgModule.providersまたはprovidedIn: 'root'で設定します。R3Injectorインスタンスの階層に格納されます。- 場所:
packages/core/src/di/r3_injector.ts
ノードインジェクター
@Component.providersまたは@Directive.providersで設定します。- クラスではなく、
LViewの内部(「Expando」セクション)に埋め込まれたデータ構造です。 - ブルームフィルター(
TView.data)を使用し、ツリーを上方向にたどる前に、特定のノードインデックスにトークンが存在するかをすばやく確認します。 - 現在のノードからトークンの解決を開始し、ビューのツリー(要素インジェクターの階層)を上方向にたどります。見つからない場合は、モジュールインジェクターにフォールバックします。
4. 変更検知
- ダーティチェック:Angular は、テンプレートにバインドされた値が変化したかどうかを確認します。
- ストラテジー:
OnPush:デフォルトです。入力が変化したとき、イベントが発生したとき、テンプレートのシグナルが更新されたとき、またはビューが明示的にチェック対象としてマークされたときにチェックします。Eager:変更検知のトラバーサルがコンポーネントに到達するたびにチェックします。(DefaultはEagerの非推奨のエイリアスです。)
- Signals:新しいリアクティビティのプリミティブです。シグナルが変化するとスケジューラーに通知し、きめ細かな更新(ゾーンレス)を可能にします。
5. 知っておくべき主要なディレクトリ
src/render3:Ivy レンダリングエンジンです。instructions:コンパイルされたコードから呼び出されるランタイム命令です。interfaces:LView、TView、TNodeの定義です。
src/di:依存性注入システムです。src/change_detection:変更検知のロジックです。src/zone:Zone.js との統合です。src/render3/reactivity:primitives/signalsのリアクティブグラフを基盤とする、シグナルの実装(signal、computed、effect)です。
6. 規約と注意点
- プレフィックス:プライベートまたは内部のエクスポートは、多くの場合
ɵで始まります。 - グローバル状態:Ivy は、命令の実行中にコンテキスト引数をあらゆる場所で渡す必要をなくすため、グローバル状態(例:
getLView())に大きく依存しています。これはパフォーマンスとコードサイズのためです。 - パフォーマンス:コードは、パフォーマンスとメモリ効率を高めるために高度に最適化されています。オブジェクトの代わりに配列を使う方法、ビットマスク、手動メモリ管理のパターンが使われています。これらのパターンを尊重してください。
7. コアを変更する方法
- 命令を理解する:ランタイムの動作を変更する場合は、
src/render3/instructions内の対応する命令を見つけてください。 LView/TViewへの影響を確認する:状態を追加する場合は、LView配列内のどこに配置するかを理解してください。- テスト:コアには広範なテストがあります。Bazel を使って実行してください。