GitHub日本語訳しながらngIvyの設計を理解する。要点だけまとめると以下。おける分離コンパイルの課題を解決できるIvyコンパイラは過去の形式を"バックパッチ"してIvy化できるので、後方互換の問題はないIvyが要求するのはコンパイル後の.jsファイルと.metadata.jsonファイルだけであり、手書きやあるいはサードパーティのツールにより生成されたコードであっても区別せず同様に扱うことができるかなりアツい。regenerated.バージョン5.0以前のAngularコンパイラは、プログラム全体の分析を行い、テンプレートとインジェクタ定義を生成します。インジェクタスコープ定義の平坦化や、コンポーネント中へのディレクティブのインライン化、クエリの事前計算、コンテンツプロジェクションの事前計算、その他に利用します。このグローバルな情報はモジュールとコンポーネントファクトリーがモジュールのコンパイル時に最終的なグローバルのステップとして生成されていることを要求します。何らかの推移的な情報が変更されたときには、すべてのファクトリーが再生成される必要があります。decorators.コンポーネントやモジュールのコンパイルの分離は、モジュール定義レベルで、ソースコード状態からのみサポートされています。それはつまり、npmパッケージはファクトリーを生成するためのメタデータを持つ必要があり、生成されたファクトリを含めてはいけないということです。依存パッケージがひとつでも変化すれば、そのファクトリーは無効になり、依存パッケージの中でバージョン範囲を使うことを防ぐからです。ここよくわからない)(すでにTypeScriptからJavaScriptに翻訳された)コンパイル済みのソースからファクトリを作成するためには、ライブラリはAngularデコレータの中身を記述したメタデータを含める必要があります。runtime.このドキュメントではこのスタイルのコード生成をランタイムで使うレンダラークラスの名前より、Renderer2と説明します。recompiled.Ivyにおいては、ランタイムはこれまではコンパイラによって事前計算されたもののほとんどを、実行時に処理することで分離コンパイルを可能にする方法で作られています。これにより、コンポーネントの定義はそれに依存するモジュールやコンポーネントがリコンパイルされることを要求することなく変更できるようになります。ngc.このIvyのメンタルモデルは、デコレータがコンパイラであるということです。それはつまり、デコレータは、デコレータのパラメータを基に定義を生成することによりクラスを変換するトランスフォーマーへのパラメータとして考えられるということです。@ComponentデコレータはngComponentDef静的プロパティを追加することでクラスを変換し、@DirectiveはngDirectiveDefを追加し、@PipeはngPipeDefを追加し、その他もそうです。ほとんどのケースで、デコレータに与えられる値は定義を生成するために十分です。テンプレートの解釈においては、コンパイラはそのテンプレートのスコープ中にあるそれぞれのコンポーネント・ディレクティブ・パイプのために定義されたセレクターを知っている必要があります。このドキュメントの目的はコンパイラから必要とされる情報と、その情報が発見されその後のngcの呼び出しに使われるために、どのようにシリアライズされるかを定義することです。Renderer2.このドキュメントではこのスタイルのコード生成を、それを作るプロジェクトのコードネームより、ivyと説明します。Renderer2とよく似ているRenderer3として説明するほうが一貫性があるかもしれません。5においてコンパイルを超えて有効な情報はコンパイラ中でサマリーの記述として表されます。コンポーネントやディレクティブはCompileDirectiveSummaryとして表されます。以下のテーブルはこの情報がIvyコンパイル後クラスの中で確定する場所を示します。information.クラスにつきたった1つの定義が生成されます。すべてのコンポーネントはディレクティブであるため、ngComponentDefはngDirectiveDefの情報をすべて内包します。すべてのディレクティブはInjectableであるため、ngComponentDefとngDirectiveDefはngInjectableDefの情報を内包します。like:CompilePipeSummaryは次のテーブルのようになります。scope.定義に生成されない情報はディレクティブのセレクターとパイプの名前だけです。それらはモジュールのスコープに入るからです。them.ngModuleScopeを組み立てるために必要な情報はディレクティブやパイプからそれらが宣言されるモジュールへのコミュニケーションが必要になります。5は.tsファイルから直接推定され、TypeScriptにより作成される.d.tsファイルには含まれない値の情報を保存するために.metadata.jsonファイルを使います。.d.tsファイルには型のエクスポートだけが含まれていて、必要な値のエクスポートを含まないので、メタデータは.tsファイルからのexport文を含みます。index.モジュールがFESMに平坦化されるとき、そのモジュールのインデックスからエクスポートされるすべてのシンボルのメタデータである、フラットメタデータファイルも作成されます。フラットメタデータは.metadata.jsonファイルがすべてのシンボルがインデックスからの再エクスポートではなくそのインデックスで宣言されているかのように表現します。decorator.IvyにおけるクラスのメタデータはIvyコンパイラにより変換された.jsファイルのメタデータになるように変換されます。コンポーネントの@Componentはコンパイラにより削除され、ngComponentDefに置き換えられます。.metadata.jsonファイルは同じように変換されますが、値の中身は除外されます。{}のように)コンパイラはコンポーネントのために宣言されたセレクターを記録しませんが、ngModuleScopeを作るために必要です。したがって、その情報はngSelector静的フィールドが@Componentあるいは@Directiveデコレータのselectorフィールドの値と共にクラスに宣言されているかのように記録されます。performed:次のような変換が実行されます。manually.ngcコンパイラが実行されるまえに、手作業あるいは他のコンパイラによる変換が完了している場合は、正確にこのとおりに作成するように注意してください。それはつまり、このモデルはコンパイラによる魔法は存在せず、@Componentにより修飾されたクラスは手作業で作られたものと同一に扱われるという利点があるということです。type:スコープの値は次のような型の配列です。as:次のように手作業で書かれたとしても、生成されたものと同一であることが重要です。}という値を生成します。これはこのシステムが手作業で作られたモジュール定義と機械的に作成されたモジュール定義の違いを無視できるようにします。compiler.このプロポーザルでは、コンパイラは手書きのAngular定義と機械的に生成されたAngular定義を同一に扱います。これは将来的にその定義を機械的に作成する方法を柔軟にするだけでなく、定義を生成する代替のメカニズムを、コンパイラや依存するツールチェインに手を加えることなく簡単に探究できるようにします。異なるコンポーネント構文を持ったサードパーティのコード生成器が、完全にコンパイラから理解可能なコンポーネントを作成することも可能にします。JSXとかのことを指している。declaration.しかし残念ながら、手書きのモジュールは実行時には不要なクラスへの参照を含んでいます。@__BUILD_OPTIMIZER_REMOVE_コメントで修飾することでAngularが生成したコンポーネントプロパティを同じペイロードにできます。@__BUILD_OPTIMIZER_REMOVE_コメントを含むことでプロパティのペイロードを改善できます。application.ngcが扱えるケースはアプリケーションを作成することと、アプリケーションから使われる再利用可能なライブラリを作成することです。5のRenderer2形式の出力により生成されるファクトリを生成できます。Ivyにおいては、ファクトリで生成された情報はAngularのなかでデコレートされたクラスの静的フィールドとして生成された定義として生成されます。compiled.最終的なアプリケーションをビルドするとき、Renderer2はすべてのライブラリのすべてファクトリが生成されることを要求します。Ivyにおいては、ライブラリがコンパイルされるときに定義は生成されます。class.IvyのコンパイルはRenderer2をターゲットにしたライブラリをファクトリを生成し、バックパッチを行いランタイムで静的プロパティを追加することにより採用できます。classes.アプリケーションがRenderer2ターゲットライブラリを含む時、Ivy定義がそのコンポーネントやディレクティブ、モジュール、パイプ、Injectableクラス上にバックパッチされる必要があります。false.Angularコンパイラオプションのrenderer2BackPatchingが有効な時、コンパイラはangular.back-patchモジュールをプロジェクトの出力ディレクトリのルートに生成します。generateRenderer2Factoriesがtrueの場合は、renderer2BackPatchingのデフォルト値はtrueになり、falseにするとエラーになります。renderer2BackPatchingはenableIvyがfalseのときは無視されます。'_'.angular.back-patchはすでにコンパイルされたライブラリを含むアプリケーション全体の@NgModuleごとに関数をエクスポートします。関数名はインポートされたモジュールの名前を、/や.を含むアルファベットでない文字を_に置換して決定されます。created.バックパッチ関数はそれがインポートする他のモジュールのバックパッチ関数を呼び出します。これが意味するのは、アプリケーションのモジュールと、遅延ロードされるモジュールのバックパッチ関数だけを呼び出す必要があるということです。Renderer2モジュールファクトリのインスタンスを使う場合は、これはアプリケーションの最初のモジュールのインスタンスが作られたときに自動的に機能します。5.0が生成するのと同じ場所にNgModuleFactoryの実装を生成できます。このNgModuleFactoryの実装は最初のモジュールインスタンスが作られたときに、angular.back-patchモジュールに生成された正しいバックパッチ関数を呼び出すことにより、Renderer2形式のクラスをバックパッチします。false.Renderer2形式のファクトリはgenerateRenderer2FactoriesAngularコンパイラオプションがtrueのときに作成されます。generateRenderer2Factoriesを設定すると、renderer2BackPatchingも暗黙的にtrueになり、明示的にfalseにするとエラーになります。generateRenderer2FactoriesはenavleIvyがfalseのときは無視されます。5.0と同じ場所に同じパブリックAPIで作成されます。areIvyアプリケーションを作成するための推奨オプションは次のとおりです。explicitly.impliedと記されたオプションは他のオプションにより暗黙的に推奨される値を持つため、明示的に設定する必要はありません。defaultと記されたオプションも同様に明示的に設定する必要はありません。below.Ivyライブラリをngcを使ってビルドするのは、その定義が生成された出力に含まれる点と、それがnpmに公開されるパッケージに含まれるべきであるという点で、Renderer2と違います。.metadata.jsonファイルはまだ同梱が必要ですが、後述のように変換されます。class.先述のとおり、コンパイラがクラスに宣言を追加するとき、コンパイラはクラスに追加された新しい静的フィールドを反映するように.metadata.jsonも変換します。file.一度静的フィールドがメタデータに追加されると、Ivyコンパイラはもうデコレータの情報を必要としません。enableIvyがtrueであるとき、この情報は.metadata.jsonファイルから削除されます。are:Ivyライブラリを作成するときの推奨オプションは次のとおりです。explicitly.impliedと記されたオプションは他のオプションにより暗黙的に推奨される値を持つため、明示的に設定する必要はありません。defaultと記されたオプションも同様に明示的に設定する必要はありません。target:デフォルトのAngularコンパイラオプションは殆どの場合、推奨されるオプションのセットですが、特定のターゲットに設定するのに必要なオプションが明確ではなく、それらを混合すると無意味な結果が生じる可能性があります。targetオプションはコンパイラオプションをターゲットに依存した推奨値に設定するのを簡略化するために利用できます。provided.enforcedと記述されたオプションは、もし明示的に異なる値が設定されたときにエラーを報告します。requiredと記述されたオプションは設定されることを要求し、もし値がなかった場合はエラーメッセージを表示します。targets.applicationターゲットはルートアプリケーションモジュールを含むngcの実行時に使われるオプションを目的とします。遅延ロードされるモジュールもapplicationターゲットで考慮されるべきです。module.libraryターゲットはルートアプリケーションモジュールや遅延ロードモジュールを含まないすべてのngcの実行時に使われるオプションを目的とします。target.packageターゲットはnpmパッケージのエントリポイントとなるライブラリパッケージを作成することを目的とします。それぞれのエントリポイントはpackageターゲットを使って個別にコンパイルされるべきです。like,Renderer2アプリケーションを作成するためのオプションは次のようになります。out.あるいは、applicationオプションはデフォルト値なので、angularCompilerOptionsは省略できます。like,Renderer2ライブラリを作成するためのオプションは次のようになります。like,Renderer2パッケージを作成するためのオプションは次のようになります。like,Ivyアプリケーションを作成するためのオプションは次のようになります。like,Ivyアプリケーションを作成するためのオプションは次のようになります。6.0ではサポートされません。IvyアプリケーションはRenderer2ライブラリをサポートするので、npmパッケージはすべてRenderer2ライブラリであるべきです。application.ng_moduleルールは再利用とアプリケーションへの組み込みが可能なAngularライブラリを作成するのに必要なソースを記述します。correctly.ng_moduleルールはAngular出力をつくるためにngcを呼び出します。ng_moduleは普通は使われない.ngsummary.jsonファイルの機能を使い、正しく設定することが難しいです。rules..ngsummary.jsonはコンパイラが生成されたファクトリを使うのに必要なすべての情報を記述します。.ngsummary.jsonはng_moduleルールで定義されたアクションにより生成され、別のng_moduleルールに依存するng_moduleルールにより定義されたアクションにより使われます。file.ng_moduleルールはまだngcをAngular出力を得るために使いますが、Ivy出力を生成するときには、.ngsummary.jsonファイルはもはや必要ありません。ng_experimental_iv_srcs.ng_experimental_ivy_srcsは生成されるファイルのIvy版を発生させる手段として利用されます。ng_experimental_iv_srcsに移動することを意図しています。sources.ng_moduleは.jsファイルのIvy版を提供できます。それは開発用の.ivy.jsと、プロダクション用の.ivy.closure.jsを生成します。be:ng_moduleルールはangular.back-patch.jsと.closure.jsファイル、module_scope.jsonファイルも生成します。module_scope.jsonファイルの型は次のようになります。location.moduleNameがある場所はソースツリーのなかで同じ相対位置の.tsファイルのimport文に登場するような名前です。このファイル中のすべての参照はこの位置からの相対です。bazel:一般的なAngularアプリケーションのBazelビルドは次のようになります。add:Ivy版を生成するには次のように追加します。run:Renderer2版をserveするには次のように実行します。runIvy版をserveするには次のように実行します。removed.ng_experimental_ivy_srcsルールはIvyがエクスペリメンタルである間だけ必要です。Ivyがリリースされたあとは、ng_experimental_ivy_srcsと依存するルールは削除できます。読者になる@laco2netをフォローらこらこファンクラブhttps://www.patreon.com/lacolacoPatreonで支援を受け付けています。(5)月別アーカイブはてなブログをはじめよう!lacolacoさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。