Angular: 大規模プロジェクトのNgModule

作成日 2016年08月07日  ·  144コメント  ·  ソース: angular/angular

送信しています... (「x」でチェックしてください)

[X] feature request / proposal

私はNgModuleについて読んでいますが、現在の提案(https://docs.google.com/document/d/1isijHlib4fnukj-UxX5X1eWdUar6UkiGKPDFlOuNy1U/pub)が考慮に入れているかどうか完全にはわからないいくつかのユースケースをレイアウトしたいと思います。 。

環境

私はエンタープライズフレームワーク(Angular 2に基づく)を構築するチームの一員です。 このフレームワークは、同じエコシステム内の他のアプリのベースになります。

フレームワークをより小さなプロジェクト/モジュールに分割しました(それらを別々のnpmパッケージと考えてください)。 これらのモジュールは、コントロールのセット(他のモジュールで再利用される)またはそれらのコントロールを使用するページです。

簡単な例は次のとおりです。

制御モジュール

import {Component} from "@angular/core";

@Component({
   selector: "my-combobox",
   ...
})
export class MyComboBox{

}

チェックリストモジュール
//チェックリストモジュールはコントロールモジュールに依存します。 コントロールはサードパーティのモジュールとして扱われます。

import {Component} from "@angular/core";
import {MyComboBox} from "controlsmodule/components/mycombobox";
// Please note that we are only loading a specific component within the module, not all components inside that module.

@Component({
     selector: "my-checklist-page",
     directives: [MyComboBox, ...],
     ...
})
export class ChecklistPage{

}

Bootstrapは、コントロールモジュールとチェックリストモジュールの両方を認識していません。 それらは、ユーザーの操作に応じて遅延ロードされます。 この場合、ユーザーがチェックリストに移動すると、ChecklistPageコンポーネントが読み込まれ、MyComboBoxもそれに続きます(ChecklistPageによって作成された_import_のため)

チェックリストモジュールには、他にも多数のコンポーネントがあります。 それぞれが複数のモジュールからの他のダースのコンポーネントに依存しています。

すべてのコンポーネントをNgModule宣言にインポートすることは非現実的です(ほぼ不可能とは言えません)。 アプリの実行時に使用される可能性のある数百のコンポーネントについて話します。

また、アプリケーションは、可能な場合はモジュール式で遅延読み込みする必要があります。 アプリ内での相互作用が異なると、まったく異なるモジュールが読み込まれます。

期待される/望ましい動作

コンポーネントスコープのディレクティブを使用する現在のソリューションは、このユースケースの魅力のように機能します。 これがNgModuleでどのように機能するかわからない。

それ以上に、現在、各コンポーネント(この場合はChecklistPage)に必要な依存関係を明確に確認できます。 メンテナンスがはるかに簡単になります。

必要なすべてのコンポーネントをNgModuleにインポートし、それらをいくつかのコンポーネントで不明瞭に使用することは、小さなアプリケーションにとって素晴らしいソリューションのようです。 長期的な開発では、複数年にわたる複数の反復、チームのローテーション、...テンプレートを調べずに各コンポーネントに依存関係を明示的に示す(そして何かが欠落しているときにコンパイルエラーが発生する)のは素晴らしいことだと思います。アドバンテージ。

結論

説明が明確かどうか教えてください。 この問題の目的は、この状況についての認識を高め、進め方についてフィードバックを得ることにあります。

現在の作業を紹介することができます。昨年開発された8つのプロジェクト全体で数百のAngular2コンポーネントがあります(アルファ27以降)。

最も参考になるコメント

皆様からのフィードバックに感謝します。返信を受け取るまでに時間がかかったことをお詫びします。先週は非常に忙しかったです(内部のGoogleアプリをNgModulesに移行しているため、リファクタリングの苦痛も感じています)

ここでいくつかの質問や誤解を解くことができるかどうか見てみましょう。

@NgModule()(および@Componentやその他のAngukarデコレータ)について最初に理解することは、これらは純粋にコンパイル時のコンストラクトであるということです。Angularコンパイラがアプリケーションの依存関係グラフを検出できるようにするために存在します。

デコレータが行うことの(簡略化された)バージョンは次のようになります。

//simplified Component decorator
export function Component(componentConfig){
  return function(componentClass){
    Reflect.defineMetadata('annotations', componentConfig, componentClass);
  }
}

装飾されたクラスの動作を変更または変更することはありません。メタデータを添付するだけです。 Angularはそのメタデータを使用して、アプリケーションを構築し、テンプレートをコンパイルします。

JiTモードでは、これは「ジャストインタイム」で発生します。bootstrapModuleを呼び出してから最初のコンポーネントレンダリングを行うまでの間に、AngularのコンパイラはReflectAPIを使用してクラスにアタッチされたメタデータを取得します。

let metadata = Reflect.getOwnMetadata('annotations', componentClass);

ただし、AoTモードでは、これは少し異なる動作をします。ビルド時に、デコレータをスキャンすることにより、ソースコードから同じメタデータを_静的に_(つまり、コードを実行せずに)抽出します。

これは、単一のコンポーネントをブートストラップする場合は問題なく機能しますが、複数のルートコンポーネントをブートストラップしたり、認証ステータスに基づいて異なるコンポーネントをブートストラップしたりするなど、より複雑なことを行っている開発者から多くのフィードバックを聞いています。

したがって、@ Componentデコレータはコンポーネントを静的に分析する機能を提供しましたが、 _Application_を確実に静的に分析する機能はありませんでした。

「アプリケーション」の傘下にあるもの

  • PLATFORM_DIRECTIVES / PIPES / PROVIDERS
  • 以前にbootstrap()に追加したもの
  • コンパイラレベルの設定
  • 複数のルートコンポーネント
  • サーバー側の使用法。

NgModulesは、静的に分析可能な一連の機能の概念を導入します。 興味深いのは、AoTコンパイルモードで、ルートモジュールを分析し、アプリケーション内の各モジュールのModuleFactoryを_生成_することです。これはモジュールのコンパイル済みバージョンであり、テンプレートで静的に参照するファクトリと「entryComponents」としてマーク

事前コンパイルに必要な情報をすでに抽出しているので、実際にデコレータをツリーシェイクすることができます(ngcはこれを最終的に自動的に処理します)-ルートモジュールからアプリケーションをバンドルするのではなく、開始します生成されたルートでModule_Factory_は、アプリケーションで実際に使用されるコードのみを含むため、モジュール性にペナルティを支払う必要はなく、rollupやwebpack2などのツールは_より効率的に_動作できます

次の返信でフォローする詳細...

全てのコメント144件

ngModulesが目的のセットアップを禁止しているようには見えませんが、もう遊んだことがありますか? 複数の異なるモジュールを使用して、遅延読み込みなどを行うことができます。http://plnkr.co/edit/NAtRQJBy50R19QAl90jg ?p = info

あなたがやろうとしているように見えることにもっと似ていることについては、目を離さないでください。material2の遷移: https ://github.com/angular/material2/pull/950/files

こんにちは@qdouble

迅速な返信ありがとうございます。
https://github.com/jelbourn/material2/blob/ecbb4f42e0473899f6ad15d8e4ed8f262ded7a99/src/components/button-toggle/button-toggle.tsを見て、現在と同じ機能を実現するには、各コンポーネントでNgModuleを宣言するには? (それはファイルの最後に追加されたものですよね?)

また、最初のステートメントで述べたメンテナンスの問題については説明していません。 各コンポーネント/ディレクティブの依存関係をデコレータで宣言することは、私にとって、維持したい大きな利点です。

@jpsfsコンポーネントごとに個別のスコープを作成したい場合は、コンポーネントごとに異なるngModuleを作成する必要があると思います。 これにより、あなたのケースではより多くのコードが作成される可能性がありますが、コンポーネントごとではなくモジュールをスコープすることで、他の大多数の人々のために作成されるコードが少なくなると思います。

2番目の問題に関しては、ngModuleとコンポーネントを隣り合わせに宣言できるため、ファイルに3行または4行のコードが追加されますが、大きな問題になるとは思いません。

ユースケースの大部分は、コンポーネントごとにスコープ付きディレクティブを必要としないと思いますが、必要な場合でも、ngModulesはさらに数行のコードでそれをサポートします。

@qdoubleありがとう。

これがまたは/または状況であるかどうかはわかりません。両方のシナリオが連携して機能していることがわかります。すでに持っている機能を削除する必要はありません。 誰かがモジュールを使いたいのなら、それは素晴らしい追加だと思います。 一方、フレームワークはモジュールなしで機能する可能性があります(現在機能しているため)。 オフラインコンパイルの問題でも、現状のままで解決できると思います。

私はこれを開いて、誰かが問題に追加する何かを持っているかどうかを確認します。

@jpsfsは理解しました、もし私があなたの状況にあったら、私は間違いなく彼らが両方のオプションを開いたままにしておくことを望みます:)

彼らは、2つのスコープを作成する限り、ngModuleスコープが十分に小さく、ES6モデルとより一致していると考えて、投稿したドキュメントにコンポーネントディレクティブを非推奨にする理由を書きました。

チームメンバーはまた、物事を行うための2つの異なる方法があることは一般的に問題があると述べました...そして長期的には、ここで問題を見ることができます....人々がngModulesや他のプロジェクトを使用しているプロジェクトがある場合ない場合は、メンテナンス、トレーニング、互換性の問題がさらに発生します。

このプロジェクトが最終的にどの方向に進むかわからないので、彼らがあなたの言っていることを考慮に入れているかどうかを確認します。

私でさえ、現在、巨大なエンタープライズアプリのアーキテクチャの設計に取り組んでいます。
あなたの状況@jpsfsとは異なり、私はNgModulesに興奮しており、NgModuleを中心としたアプリアーキテクチャにほぼ基づいています。

各モジュールには、独自のルートとコンポーネントの依存関係のセットがあります。 1つのコンポーネントだけで機能を作成することはできません。それには、ルート、少なくとも1つのスマートコンポーネント、およびいくつかのダムコンポーネントとサービスが必要です。 これをすべてモジュールに接続すれば、準備は完了です。

遅延読み込みでは、各コンポーネントのコードを読み込むのではなく、各NgModuleコードが一度に読み込まれるように見えるため、ダウンロードすると機能が完全に使用可能になります。

モジュールの階層の作成もはるかに簡単で、優れたプラグアンドプレイ機能を無料で提供します。

現在、非常に多くのコンポーネント(数百ではなく数十)を使用するアプリケーションにも取り組んでいます。 このアプリケーションをいくつかの(遅延ロードされた)モジュールに分割するアーキテクチャ上の必要はありませんが、これらすべてのコンポーネントをブートストラップファイルにインポートしてdeclarationsに渡すと、どういうわけか間違っていると感じ、コンポーネントのカプセル化が壊れます。 @jpsfsが言ったように、どのコンポーネントとディレクティブが別のコンポーネントによって使用されているかが非常に明確になる前に。 だから私も選択肢を持っていただければ幸いです:

  • かなり一般的に使用されるディレクティブの場合は、モジュールで宣言します
  • TaskListItemのようなものであれば、 TaskListにインポートするだけです。

たぶん、一部のコアメンバーは、2番目のアプローチを廃止する決定についてもっと話すことができます。 数ヶ月間使ってきたので、かなり気持ちがいいです;)

@choellerの主張を反映すると、コンポーネントのカプセル化を提供する機能から離れるのは奇妙に感じます。

私が特に懸念しているのは、コンポーネント名/セレクターがアプリ全体にリークするのに対し、以前は、必要に応じて特定のディレクティブを含めることで、さまざまなコンポーネントのセレクターを再利用できるようになったことです。

これで、すべてのセレクターはコンポーネントごとに一意である必要がありますよね? それとも、これがどのように機能するかを誤解していますか?

元の機能は、大規模なアプリ間でのセレクターの衝突などの心配が少ないという点で、CSSシャドウDOMエミュレーションによって提供される同様の利点と一致していると感じました。 それはIMOの大きなアドバンテージでした。

ngModuleについて最初に考えたのは、「ああ、それは角度1のようなものです」でした。 角度1がすでにあったのと同じくらい、角度2は非常に多くの点ではるかに優れています。 私にとっての最良のポイントは、コンポーネントが何らかの依存関係ツリーを作成することでした。 ルーターを備えたメインコンポーネントがあり、独自のコンポーネントを使用していくつかのエントリポイントを定義しています。 そして、すべてのコンポーネントはそれが何を必要としているかを知っています。ツリーの最後にあるコンポーネントが何を必要としているかをメインコンポーネントが知る理由はありません。
これで、Angular 1の古き良き時代に戻り、巨大なモジュール定義があります。
アプリのエントリポイントがこのようになっていたことを覚えていますか?

angular.module("myApp")
.controller("…")
.controller("…")
.controller("…")
.controller("…")
.controller("…")
.controller("…")
.component("…")
.component("…")
.component("…")
.component("…")
.component("…")
.component("…")
.directive("…")
.directive("…")
.directive("…")
.directive("…")
.directive("…")
.directive("…")
.directive("…")
.service("…")
.service("…")
.service("…")
.service("…")
.service("…")
.service("…")

これは過去のものだと思いました。 私はng-metadataを使用して、古いAngular 1プロジェクトを改善し、移行の準備を始めました。 グローバルな「このアプリに表示される可能性のあるもの」リストではなく、依存関係ツリーがあるという事実が本当に気に入っています。

これにより、再利用可能なコンポーネントがより困難になります。 これにより、すべてがグローバル/モジュールスコープにあるとどうなるかわかりません。ng2チームは、変更を望まないng1ユーザーに屈服したと思います。

@DaSchTour @damiandennisこのアーキテクチャに対する批判は理解していますが、ある種のグローバルスコープが不正確であると言及しているため、彼らが提案している方法論は、機能モジュールを用意することです: https ://angular.io/docs/ts

@qdoubleええと、結局はすべてのコンポーネントをモジュールに変更するだけです。 これはボイラープレートコードを減らすための変更として発表されていますが、ボイラープレートの必要性がたくさんあります。

RC4までは、アプリケーションのすべての「ページ」/ビューのコンポーネントで十分でしたが、すべてのビューのモジュール、コンポーネント、およびルーティングを作成する必要があることを知っておいてください。 意図があります。 しかし、私はどういうわけか、他の多くの点を気にせずに、いくつかのことを簡単にするように設計されているという印象を持っています。 また、機能モジュールパターンを使用しても、依存関係地獄を回避するために、アプリケーションのどの部分にどのコンポーネントが必要かわからないため、必要になる可能性のあるすべてのものを追加することで、それらを非常に小さくカットする必要があります。

結局、モジュールは非常に小さいので、現在のコンポーネントと同様の反復的な依存関係リストがあります。

結局、それはそれが設計されたものを解決せず、多くの作業を追加するだけです。 ここではデザインとリアリティの間にミスマッチがあるような気がします。

開発者は怠惰で時間が足りず、近道をします。 これにより、開発者はすべてをブートストラップに含めるという迅速な方法を取ることができます。 少なくともコンポーネントでは、依存関係を含める必要があります。 はい、それらは怠惰で、アプリケーション全体に対して単一のコンポーネントを作成する場合もありますが、依存関係はすべてそのコンポーネント内にあり、ブートストラップファイルとアプリケーション内の各コンポーネントファイルの間で混同されないため、修正が容易です。

@DaSchTour個々のコンポーネントが独自のスコープを必要とする場合、はい、それはより多くの定型文を作成します...しかし、ngチームは、ほとんどの人にとって、すべての機能セクションに新しいモジュールを作成するという意見だと思います十分であり、いくつかのコンポーネントが各機能スペースに存在できます。

明らかに、すべてのソリューションに適合する人は誰もいません。コンポーネントレベルのディレクティブを使用する方が簡単な場合もあります。 ただし、ここでのコメントの多くは、1つの巨大なngModuleツリーを使用してアプリケーションを作成することを望んでいることを示唆しているようです...

批判が、彼らが提案していないストローマンのデザインパターンではなく、実際のデザイン提案に基づいている場合(つまり、1つの巨大なngModuleであるエンタープライズアプリを作成すること)は、より生産的だと思います。

@qdoubleデザインパターンはシンプルです。 依存関係をグローバルなモジュールスコープに移動する代わりに、依存関係ツリーを使用します。 重要な点は、再利用可能なコンポーネントは、非常に小さく、機能がほとんどない場合でも、モジュールでなければならないということだと思います。 Angularmaterial2は非常に良い例です。 ボタンは、1つのコンポーネントを含むモジュールです。 モジュールは単なるボタン以上のものであるというのは、多くの開発者の一般的な誤解かもしれません。 そして今、さらに一歩考えてみましょう。 この記事のアイデアに従ってくださいhttps://angularjs.blogspot.com/2016/08/angular-2-rc5-ngmodules-lazy-loading.html私はその時点で自分自身を見つけ、モジュールがたくさんあることに気づきました。角度のあるmaterial2モジュールのリストと、単一のコンポーネントで構成されるこの各モジュールをインポートします。
ファクトでは、これはまさに角度のあるmaterial2が行うことです。

誰も本当に重要なことはわかりません。なぜ今、すべてのコンポーネントをモジュールにラップする必要があるのですか。 あるいは、これを宣言の分割と見なす必要があるかもしれません。 コンポーネントの依存関係がモジュールになり、コンポーネントの定義がそのままになりました。

重要なのは、ngModulesは物事を簡単にするための優れた追加機能であるだけでなく、すべてを変更することを余儀なくされているということです。 たぶん誰かが、なぜ両方が共存できないのかを明確に説明する必要があります。

@DaSchTourはい、作成するすべてのコンポーネントに独自のモジュールが必要な場合は、ngModulesを使用するとより多くの定型文が作成されることに同意します...チームは、ほとんどの人がすべてのコンポーネントに対してそのレベルの分離を必要とするとは考えていません。成分。

私は、Angular Material2モジュールのリストをインポートするモジュールがたくさんあり、この各モジュールが単一のコンポーネントで構成されていることに気づきました。

これには共有モジュールを使用します: https://angular.io/docs/ts/latest/guide/ngmodule.html#! #shared-module

さて、なぜコンポーネントスコープを持つ機能を完全に削除する必要があると彼らが考えるのかはよくわかりませんが、私にとっては、ngModuleの使用を実際よりも難しくしたり、デザインをより見栄えよくしたりするという批判もあります実際よりもずさんです。

コンポーネントスコープのディレクティブ/パイプを削除することへの批判は完全に正しいと思います。 ただし、ngModuleのデザインパターンが適切でないように見せかける必要はないと思います。

@qdoublengModulesに優れたデザインパターンがあることを疑う人はいないと思います。 しかし、私が理解していることから、モジュールは一連のコンポーネントのラッパーにすぎず、それらを公開するためのディレクティブとサービスはアプリケーションのユニットです。 それは有効で素晴らしいアイデアです。 しかし、なぜコンポーネントではなくモジュールの依存関係(モジュール内にのみ存在する可能性がある)を定義する必要があるのですか?

@choellerを例に取る
モジュールTaskDashboardには次のものがあります

  1. タスクリストコンポーネント
  2. Taskitemコンポーネント
  3. Taskfilterコンポーネント
  4. タスクサービス

Taskitemコンポーネントは、Tasklist内でのみ必要であり、TasklistはTaskitemコンポーネントに依存します。 TaskfilterはTaskitemコンポーネントを必要としません。 現在、タスクリストに依存関係としてのタスクアイテムがありません。 次のステップは、TaskSearchモジュールを作成することです。 以下のものを追加します。

  1. タスクリストコンポーネント
  2. Tasksearchコンポーネント
  3. タスクサービス

さて、私はTaskitemコンポーネントを見逃しました、そしてそれは壊れています。 Tasklistは常にTaskitemに依存しますが、この依存関係はモジュールに隠されています。 コンポーネントの再利用はより困難になり、追加のエラーの原因になります。

さて、モジュールガイドをさらに読んでいると、この行が見つかりました

コンポーネント、ディレクティブ、およびパイプは、正確に1つのモジュールに属している必要があります。

したがって、この例は、ここで提起された懸念を正確に示しています。 共有コンポーネントはあり得ません。 したがって、私の例から、すべてをモジュールに分割する必要があります。

ngModuleを使用しているときに発生する奇妙でわかりにくいエラーに取り組んでいるときに、コンポーネントの拡張が以前ほどうまく機能しないこともわかりました。 必要な依存関係を備えた一連のコンポーネントがあり、それらを簡単に拡張できました。 次に、拡張コンポーネントを含めるモジュールに依存関係をインポートする必要があります。

あなたの例の@DaSchTourでは、TaskitemはTasklist Moduleの一部である必要があります...これにより、論理的には1つのモジュールに2つのコンポーネントがあり、それぞれに1つではありません。

@sirajcが指摘したように、典型的なデザインパターンは、1つのトップスマートコンポーネントとそれに続く追加のダムコンポーネントを持つことです...したがって、典型的な現実世界のアプリでは、ほとんどのモジュールはいくつかのコンポーネントで構成されます(スマート/ダムによるかどうかは関係ありません)。コンポーネントパターンまたは関連する機能パターンによる)。サードパーティのコンポーネントなどを構築する場合を除いて、モジュールごとに1つのコンポーネントだけではありません。

@qdouble @DaSchTour新しいアーキテクチャは、必ずしもすべてのコンポーネントを1つのファイルにリストすることを意味するわけではありませんが、私たちが構築しているアプリを見ると、現在、 @ DaSchTourのこのステートメントにほぼ一致します。

ここではデザインとリアリティの間にミスマッチがあるような気がします。

したがって、 TaskListItemのように、ページ上に小さな単位を表すコンポーネントがかなりたくさんあり、それらは100%特別なビューにバインドされています。 それらのページごとにモジュールを作成することは、完全にやり過ぎでしょう。 私たちの場合、複数のモジュールに分割する理由はほとんどありませんが、コンポーネントをカプセル化する理由ははるかに多くなります。

tl; dr
モジュールレベルでいくつかの依存関係を定義できるのは素晴らしいことですが、コンポーネントレベルで依存関係を定義できなくなったのは本当に悲しいことです。

@ DaSchTourmaterial2では、ボタンコンポーネントがモジュールに関連付けられてスタンドアロンになっています。 ボタンを使用する必要がある人はButtonsModuleをインポートできます。 また、モジュールコードを見ると、2つのコンポーネントMdButtonMdAnchorが含まれており、 ButtonsModule $でラップすると使いやすくなります

ファイルの重複を防ぐために、2つの概念を1つにマージするハイブリッドコンポーネント/モジュールオブジェクトを作成できるかどうか疑問に思っています。 基本的に、コンポーネントをモジュールとして一度宣言し、必要に応じてモジュールとしてインポートすることができます。 現在のアプローチを尊重しますが、定型文を最小限に抑えます。

@choellerモジュールを持つことは良い追加であり、コンポーネントレベルで依存関係を削除することは良い追加であることに同意しますが、それは間違っているように見えます。

他の人が上で書いたことを重ねて、ここでの核となる考えは、何百ものコンポーネントを含む巨大なモジュールを備えた巨大なプロジェクトの悲惨さを経験しないことだと思います。 むしろ、妥当な数の中規模のNgModuleからアプリケーションを構築することです。 それらが些細なことではないほど十分に大きく、それらの数が多くないほど十分に小さい。 断層線に沿って分割され、これは、高凝集度と低結合度という昔ながらのコンピュータサイエンスの意味での再利用とモジュール化を容易にする傾向があります。

そうすることで、モジュールは大規模なプロジェクトで再生するための非常に便利な概念になるはずです。

それは非常によく要約された@kylecordesです。 NgModulesは、アプリケーションの優れた構成に役立ちます。 小さな再利用可能なモジュールがアプリケーション全体を構成します。
その他の利点には、ディレクティブの周囲の可用性が含まれます。 以前は、アプリケーション全体にROUTER_DIRECTIVESを追加していました。 今RouterModule.forRoot()は私たちのためにそれを行います。
BrowserModule、CommonModule、FormsModuleは、各コンポーネントにディレクティブを含めるよりも理にかなっています。

もう一方のMaterialModuleはすべてを提供し、より細かい制御が必要な場合は、ButtonsModuleなどが役立ちます。
それが作曲の美しさです。 それを受け入れて、あなたのシンフォニーを作成してください

これに加えて、LazyLoadingがあります。 NgModuleがない場合、1つのルーティング可能なユニットを作成するために一緒に実行する必要のあるコンポーネントとサービスの数をどのように定義できますか。 緩いファイルをダウンロードすることはできません。これは、ネットワーク要求の膨大な数につながるためです。 それ以外の場合は、すべての依存ファイルを一覧表示するバンドラーを作成して、1つのバンドルを作成する必要があります。 NgModuleは、直感的な構文でこれを行います。

@kylecordes

他の人が上で書いたことを重ねて、ここでの核となる考えは、何百ものコンポーネントを含む巨大なモジュールを備えた巨大なプロジェクトの悲惨さを経験しないことだと思います。 むしろ、妥当な数の中規模のNgModuleからアプリケーションを構築することです。 それらが些細なことではないほど十分に大きく、それらの数が多くないほど十分に小さい。 断層線に沿って分割され、これは、高凝集度と低結合度という昔ながらのコンピュータサイエンスの意味での再利用とモジュール化を容易にする傾向があります。

これらの障害線は、アプリケーション開発者とライブラリ開発者で大きく異なるのではないでしょうか。 図書館の開発者は少数派でなければなりませんが、それが主な不満のようです。 再利用可能なフレームワークを構築する場合、モジュールサイズを最小化するという目標は、多くの余分なノイズにつながります。

@sirajc

これに加えて、LazyLoadingがあります。 NgModuleがない場合、1つのルーティング可能なユニットを作成するために一緒に実行する必要のあるコンポーネントとサービスの数をどのように定義できますか。 緩いファイルをダウンロードすることはできません。これは、ネットワーク要求の膨大な数につながるためです。 それ以外の場合は、すべての依存ファイルを一覧表示するバンドラーを作成して、1つのバンドルを作成する必要があります。 NgModuleは、直感的な構文でこれを行います。

アプリケーションのセクションのコンテナーとして機能するコンポーネントを使用するだけで、古いルーターでこれを簡単に行うことができました。 このモジュールは、必要な直接コンポーネントのみを取り込み、独自の依存関係をもたらします。 適切なモジュールローダーは、最上位のコンポーネントにすべてのサブ依存関係を含めることなく、そのコンポーネントの依存関係チェーンを(インポートを介して)ロードできます。 同じことが、ある種のモジュール解決ロジックを使用する必要があるバンドラーにも当てはまります。 つまり、遅延読み込みの観点から、開発者が最上位コンポーネントに含まれるすべての依存関係を宣言する必要がある理由はありません。

ngModuleが問題を探すための解決策であるように本当に感じます...

任意のコンポーネントを開き、そのディレクティブ配列を一瞥し、それがどのコンポーネント/ディレクティブに依存しているかを正確に知ることができるということについては、言うべきことがあります。 ボタンコンポーネントを使用する多数のコンポーネント全体にボタンコンポーネントをインポートする必要があるのは、より冗長ですか? はい。ただし、コンポーネント/モジュールツリーを検索して、コンポーネントYがテンプレート内のコンポーネントXをインポートせずにどのように使用しているかを確認するよりも、ボイラープレートを追加して、明示的ですぐにスキャンできるようにしたいです。

上記の議論は、誰かがコンポーネントを互いに分離したい場合、おそらく各コンポーネントのモジュールを作成できるということです-しかし、その時点で、元のコンポーネントよりもさらに多くの定型文を書いています。

ngModuleには明らかに他の利点がありますが、アプリケーションのセクションを機能モジュールにバンドルできることには利点がありますが、明確にし、コンポーネントをカプセル化することに関しては、一歩後退したように感じます。いたるところにスコープを漏らさないコード。

ng2チームがng1からコミュニティに対して行わなければならなかった「ハードセル」の一部は、「ええ、各コンポーネントのディレクティブをインポートして宣言する必要がありますが、私たちを信頼してください。より明確であることに感謝します。アプリケーションが成長するにつれて」。 私は、チームメンバーが常にコンポーネントのごく一部しか作業していない可能性がある大規模なチーム環境で、読みやすさとスキャン可能性のために少し繰り返して苦しんでいることを大いに信じています。

少なくとも、ngModuleとdirectives / pipesプロパティが共存できない理由はわかりません。 別の方法は、ng2用に記述されたすべてのアプリケーションのすべてのコンポーネント(RC5まで)が、自明ではないリファクタリングが必要な非推奨のコードを使用していることです。 これらは、開発の後半に私が期待するような変更ではありません...正直なところ、かなり当惑しています。

ngModulesは、適切に構造化するために、基本的にほとんどのアプリケーションを書き直す必要があります...しかし、最大の誤解は、モジュールが必要なだけ大きくても小さくても、実際には特定のスコープレベルを強制しているということです。なれ。

どうしてもすべてのコンポーネントに対して新しいモジュールを作成する必要がある場合は、より多くのボイラープレート=有効になります。

ほとんどのアプリケーションでは、すべてのコンポーネントに対してモジュールを作成する必要があります=無効(特にスマート/ダムコンポーネントパターンと機能パターンを使用している場合)

今日初めて、多くの同僚が私に伝えてきたクライアントサイド/ JavaScriptの疲労を感じました。 新しいRC5モジュールを使用するためにRC4アプリケーションをリファクタリングしようとして、過去数日間で数え切れないほどの時間を失いました。

私は、このスレッドの多くの感情に間違いなく同意します。特に、コンポーネントの依存関係を構造化する方法に関して開発者に選択肢を与えることについてです。 大きなngModuleがコンポーネント間の明確な依存関係グラフを薄め、小さなngModuleが各コンポーネントに追加の定型コードを追加するのは嫌いです。 モジュールを分析するとき、私が知っているのは、参照されているコンポーネントの少なくとも1つが、モジュールのインポートまたは兄弟宣言からのものを必要としているということだけです。 モジュールを他の複数のモジュールに分割すると、基本的に、新しいモジュールに必要な依存関係を判断する際に試行錯誤が残ります(コンポーネントテンプレートを注意深く調べると多少役立ちます)。

最後に、コンポーネントをエクスポートするのを「忘れた」場合、コンポーネントは単にレンダリングされず、エラーは発生しません。 非常に平坦なモジュールグラフがある場合は簡単に見つけることができますが、レベルが多数ある場合はほぼ不可能です。

この段階で、私は落胆し、失望し、落胆しました。 開発者とビジネスの利害関係者のチームに、私が前進できるかどうかわからないテクノロジーを取り入れました。 より良いバランスが見つかることを本当に望んでいます。

この段階で、私は落胆し、失望し、落胆しました。 開発者とビジネスの利害関係者のチームに、私が前進できるかどうかわからないテクノロジーを取り入れました。 より良いバランスが見つかることを本当に望んでいます。

ここでのポイントは、このテクノロジーが本番環境に移行するのを待っている開発者が非常に多いことです。リリース候補と呼ばれていますが、新しい候補はすべて重大な変更をもたらし、アルファのように感じます。

多くのチームが新しいアプリのアーキテクチャに何時間も費やしていると確信していますが、今ではすべてがおかしくなりました。

次の重大な変更は何ですか? 想像すらできませんが、誰かが次の重大な変化を紹介する方法を見つけるのではないかと心配しています。

RC5ブログ投稿から:

ただし、Angular 2コードを作成したことがある場合は、おそらく「しかし、なぜこれらすべてをリストする必要があるのか​​!?」と自問したことでしょう。 -特にAngular2の特定のディレクティブとパイプが「特別」であることに気付いた場合-何もしなくてもアプリケーション全体で利用できます(たとえば、* ngFor / * ngIf / * ngSwitch)。

私は個人的に、かなり長い間、誰かからの質問を見たことがありません。 RC5まで、Angularチーム、オンライン学習リソース、書籍などはすべて、これらの宣言が必要な理由をかなり明確にしてきました。そして、誰もがその事実をずっと前に受け入れた(そして受け入れた)ようです。

一部が「特別」で宣言する必要がない理由についての質問については、「祝福」されることを保証するために非常に遍在する重要な「低レベル」のディレクティブのリストがあることに反対する人はいないと思います。プラットフォーム所有者(Angularチーム)がグローバルに利用できるように。

ディレクティブの単一のngModuleへの巻き上げを処理するコードがすでに存在し、そのコードがエンドユーザーには見えないように機能する場合、両方のアプローチを許可することの害は何ですか? 開発者がアプローチを組み合わせた場合に何が起こるかについての複雑さのいくつかを私は知らないかもしれないので、それは本物の質問です。 Angular 2には他にもたくさんの「分割された選択肢」があります-モデルとテンプレート駆動型のフォーム、3つの異なる言語の選択肢、入力/出力/ホストデコレーターとプロパティのアプローチ-この時点で別のものにどのような害がありますか?

先に進むことはできますが、私が言いたいのは、Angularチームとコミュニティがかなりの時間を費やして、より明確にすることは_良い_ことであり、急降下するだけであるというメッセージを打ち明けることです。常に候補者5_-かなり長い間問題になっていない解決策を私たちに提示します。

チームの誰かがチャイムを鳴らしたいと思いますか? 私はこれがエコーチェンバーになることを望んでいません-私は議論の反対側を聞きたいです。 ツール、トレーニング、または最終リリースにどれだけ近いかなどを考慮せずに、非常に大きなものが突然出てきたようです。

この議論は、非常に期待されている角度2:破壊的な変更で早期に開発を開始したい多くの開発者にとって非常に大きな問題を引き起こしました。 ベータ17以降、Angular 2に基づいた概念実証を多数行い、重要な企業や組織に採用させました。 後悔はしていませんが、うまくいったかどうかもわかりません。 最新のプロジェクトのいくつかはPOCであり、戦いはVue.jsとの戦いでした。 Angular2は明らかにその戦いに勝ちました。 しかし、今日、すべてのコードの書き直し、重大な変更、実際にはRCではないリリースにより、人々は私を追いかけ始め、それはかなり深刻になります。 私がVueまたはReactの開発を提供した場合はそうではなかったでしょうが、Angular 2が人々を信用できないため、それは非常に苛立たしいことです。

私は、Angularチームと同じリリース候補の定義を共有していないように思われます。

トピックに関しては、NgModule、私は@jpsfsに完全に共同署名します。モジュール宣言内にすべてのコンポーネントとマイクロコンポーネントをリストする必要がある場合は、どこかにprune関数があるか、モデル化の王様は、すべてが強力である可能性があるため、大規模なプロジェクトには感度が高すぎます...

この追加のより高いレベルのモジュール性はほぼ避けられなかったと思います。 そして、さまざまな競合するフレームワークは、最終的には類似したものになります。

しかし、この新しい粗粒度モジュールシステムを基盤となるモジュールシステムに完全に直交させる必要があるのか​​、それとも各トップレベルディレクトリとそれに含まれるすべてのEs6モジュールを暗黙的に作成できるのかどうか疑問に思います。粗粒度のNgModuleで構成されます。 おそらく、そのような規則駆動のメカニズムを現在のメカニズムの上に追加することができ、したがって、そのような規則に従うことをいとわないプロジェクトのNgModuleボイラープレートを削除することができます。

(もちろん、「RC」ステージでのこのような重要な変更について、ここで他の人とフラストレーションを共有します...コアチームも、すべてをやり直すことができれば、高レベルの攻撃を行ったはずです。モジュール性と、それを推進する力(遅延読み込み、事前コンパイル)は、リリース候補の段階ではなく、プロジェクトの開始にはるかに近くなります。これは人生ですが、いつでも振り返って「うまくいけば」と考えるのは簡単です。その時私たちが今知っていることを知っていた...」)

コンパイルのサポートがngModuleの出現の背後にある主な理由である場合、ディレクティブとパイプの既存のコンポーネントベースのスコープを確実に置き換えるべきではありません。
一方、ルート構成と依存関係に基づいて、Angularコンパイラは理論的にはアプリケーションコードを適切なコンパイルユニット(モジュール)に分割できます。

個人的には、この変更により、ボイラープレートが低くなり、あまりメリットがないように感じます。

モジュールを使用する代わりに、アプリケーションのユニットとしてコンポーネントを使用することもできたと言えます。 とにかく、これはおそらく人々がrc-5の前にやっていたことです。

モジュールがこのフレームワークの内部目的(遅延読み込みや関連するものなど)に必要な場合は、コードを汚染してコーディングエクスペリエンスを低下させないように、モジュールを開発者から隠す必要があります。 そして、私は保守性についてさえ話していません...

私がangular2を初めて見たとき、私は次のように考えました。 内部モジュールをAngular1から削除し、代わりにESモジュールを使用しましたが、他の変更も歓迎されました(コンポーネント、タイプスクリプトなど)

しかし、これが安定するのを待つほど、重大な変更、ドキュメントの不足、不十分なエラーメッセージのために、私はうんざりします。 これで、このNgModuleが付属し、基本的に、角度1以降に変更した少なくとも1つのすばらしいことを元に戻します。

さらに悪いことに、rc-2または3(理論的にはほぼ安定していた)で始まったアプリがある場合、優れたangular2 rc-5アプリを作成するために多くの作業を行う必要があり、顧客やその他の人に何らかの説明をする必要があります。開発者これ。 そして、私がそうしても、神はあなたが次に何を変えるかを知っており、私の仕事は衰退していたかもしれません。

Angular 2はしばらく前から初期段階にあることは知っていますが、私たちはRC-5であり、Angular 2を使用するプロジェクトはかなり堅実で、APIの観点からだけでなく、方法としても変更を行っています。 Angularで考えること。

それは良くないngForであり、いくつかのインポートが変更されるか、コンポーネントの注入が5つのリリースで3回動的に変更されますが、これは受け入れて理解できます。 アプリだけでなく、開発者がこのフレームワークで考える開発サイクルの非常に遅い段階での考え方を壊すような変更をもたらすことは、残念ながら受け入れることができません。

とにかく、あなたが見ることができるように、多くの人々は私が言わなければならないことに同意します、そして何人かはさらに怒っています。 あなたは人々が信頼する巨大なフレームワークを持っていますが(Googleがほとんどなので)、それにすべてを賭けることはできません。

新しいモジュールにテンプレートがある場合、それはコンポーネントである可能性があります。 考えてみてください。

次のステップは、すべての変数と関数をコンポーネントからモジュールクラスに移動することです。 真剣に。 次に、光沢のあるモジュール内に_すべての可能な_アクションの巨大な中央ライブラリがありました。 これは素晴らしいでしょう! なぜ宣言と依存関係の集中化をやめたのかわかりません。 そこにはさらに多くの分散型の構造化コード行があります!

コアチームの誰かがこれについて発言できますか? 前回の毎週の会議のメモから、チームは非推奨のAPIの削除を進めています。

@mhevery

私が今日アップグレードしたとき、この全体の巻き上げは私のアプリケーションを本当に微妙に壊しました。

  • コンポーネントのセレクターをクラスから要素に変更する必要がありました。これは、まったく関係のないコンポーネントでは、そのクラスがスタイル設定に使用され、突然コンポーネントのインスタンス化を開始したためです。
  • SpectrumComponentという2つのコンポーネント(セレクターなしで移動するページ全体と、セレクターで視覚化するために複数のコンポーネントで使用される1つの「共有」コンポーネント)があったため、#10850のみが存在すると確信しています。 巻き上げはそれによって混乱する可能性があります- directives:宣言はそうではありません。

私のSVGコンポーネントでは、カスタム要素を使用できないため、これは大きな問題になります。 これらのスコープを設定して、クラスセレクターがアプリケーション内の他の場所(!)でコンポーネントのインスタンス化をトリガーしないようにする方法はまだわかりません。

最近では、大規模なプロジェクトで「ベータ」と「リリース候補」(ASP.NET Coreはもう1つの注目すべき例です)の意味を無視することが流行しているようです。 しかし、文字通りどこでもアプリケーションをサイレントに破壊する可能性のある破壊的な変更に直面することは、本来あるべきよりも苛立たしいことです。 これらの変更に伴う約束がすぐに実を結ぶことを心から願っています。

ngModulesは理にかなっています。 コンポーネントレベルで宣言/提供する機能を削除しても、そうではありません。

小さな例

私はいくつかの異なるダイアログを含むアプリケーションを持っています(いくつかの単純なもの-それらをsimple-1とsimple-2と呼びましょう、そして他のコンポーネントを含む1つの複雑なもの-その複合体3と呼びましょう)。

現時点では、私は単純なフォルダー構造を持っています(明らかにアプリはこれから外れています)

- dialogs
   - simple-1 (containing single component and template for simple-1 dialog)
   - simple-2 (containing single component and template for simple-2 dialog)
   - complex-3 (contains the main complex-3 component plus a number of other internal components)
      - internal-component-1
      - internal-component-2
      - internal-service-3

私にとって、これは分離された機能モジュールに入れるのに最適な機能セットです。 だから私は追加します

   dialogs.module.ts
   - simple-1
   - simple-2
   - complex-3
      - internal-component-1
      - internal-component-2
      - internal-service-3

そして、Simple1Component、Simple2Component、Complex3Componentを宣言としてDialogsModuleに追加します。 完璧で、うまく機能し、完全に理にかなっています。

しかし...

complex-3のすべての内部コンポーネントについてはどうでしょうか。 私は今2つのオプションがあります

  • すべての外部の複雑なコンポーネントとサービスをDialogsModuleに追加します。 これは、complex-3のカプセル化を破るため、不適切な決定です。これは、ダイアログモジュール内のすべてがその内部(internal-component-1、internal-component-2、internal-service-3)を認識しているためです。
  • 複雑な3をそれ自体でモジュールにします。 これにより、スコープの問題が修正されます(また、別のモジュールからモジュールをエクスポートできるため、クライアントはラッパーモジュールをインポートするだけで済みます)が、同様のグループ(ダイアログ)のコンポーネントとモジュールが混在したままになります。

これらはどちらも実際には意味がなく、アプリケーションが拡張するにつれて、2つの間の競合は増加するだけです。

私にとって唯一の賢明な/明白な/保守可能な解決策は、モジュールを使用してトップレベルのコンポーネント(simple-1、simple-2、complex-3)をエクスポートすることですが、complex-3_component_にそれ自体の内部コンポーネントを定義させます。

/ cc: @robwormald

私は、@ kylecordesが、新しいngModulesを追加するのではなく、既存のTypescriptモジュールシステムを使用してコードのコースグレインコレクションを定義することについて以前に言ったことについて考えてきました。 Typescriptモジュールを使用してngModuleを1対1で定義する例を検討のために提出したいと思います。 コメントや考えは大歓迎です。

https://github.com/jbalbes/autoNgModule

10901

私は何かを見逃したかもしれませんが、遅延ロードされていないモジュールで依存性注入が機能する方法は、「大規模プロジェクト」にとって大きな問題になる可能性があります(私のものはそうではなく、すでに苦しんでいます)。

これは面白い。 Angular1にはすでにエンタープライズアプリケーションがあります。 また、requirejsを使用して、さまざまなモジュールのパッケージを定義しています(各モジュールには10〜20個のディレクティブ/サービス/フィルターが含まれています)。 これらのパッケージを本番用に単一のファイルにバンドルします(メインディレクティブを除く)。 ディレクティブは、使用時にアプリケーションに遅延ロードされます(必要なディレクティブを遅延ロードするコアディレクティブがあります)。

アプリケーションルーティングページテンプレートはcmsアプリケーションに格納されており、cmsユーザーはメインディレクティブベースのUIウィジェットを異なるページテンプレート間でドラッグアンドドロップできます(これが、ブラウザの読み込み時にメインスクリプトファイルのサイズを減らすためにディレクティブの遅延読み込みサポートが必要な理由です。私たちのアプリケーションのほとんどは、ディレクティブベースのウィジェットに基づいています)

Angular1を使用すると、レジスタプロバイダーへの参照を取得することで、モジュールへの遅延読み込みディレクティブを使用できます。
このタイプの遅延読み込みコンポーネントをモジュールにロードし、Angular2で可能なようにコンパイルしますか?

私は、ngModulesが問題を探す解決策であると他の人が示唆していることに同意します。 私の考えでは、LazyLoadingの潜在的な利点は、コンポーネントディレクティブ/パイプの依存関係の強制的な非推奨を正当化するものではありません。 ここでは間違っているかもしれませんが、ほとんどのアプリケーションでは、遅延読み込みによる実現されたメリットが実際には見られないように感じます。これは、ngModulesによって提供される唯一の真のメリットです。

おそらくngModulesは、開発構造/パターンをより良いものにしようと試みています(そして、おそらく成功するでしょう)が、これまでAPIについてほとんど見ていないことに基づいて、それはさらに複雑な方向に進んでいます。フォローして維持します。

また、本当に別のモジュールシステムが必要ですか?

NgModuleが、以前は対処する必要がなかった新しい種類のものを追加することに異議を唱える人は誰もいません。 そして、私は誰もが、特に非常に小さなプログラムの、失われたRC5以前の単純さを高く評価しています。 また、Angular 1には独自のモジュールシステムがあることを人々に伝えることができないのも残念ですが、Angular 2では、基盤となる言語のモジュールシステムを使用しているだけです。 おっとっと。

ただし、実際には、大企業の多くの技術リーダーやその他の意思決定者を含め、遅延読み込みやテンプレートの事前コンパイルに非常に興味を持っている人がかなりいます...どちらも実質的に有効ですNgModuleによる。

ただし、もう1つ。 新しいAngularモジュールについて私が最も気に入らない部分は名前です。 モジュールという言葉は、とても過負荷です。 昨日ここで他の開発者のためにこれについて話していましたが、代わりに「パッケージ」という言葉のように、似たようなアイデアをうまく​​捉えており、少なくとも同じ名前の競合するものはたくさんありませんJavaScriptエコシステムで。

名前に関する@kylecordesの問題https://github.com/angular/angular/issues/10087

そこに提示されているロジックは、「モジュール」という単語を使用しても失格になるのではないでしょうか。それは、それ以上ではないにしても、多くの概念と競合するためです。

@Barryroweは、自分でそれを改善することはできませんでした-実際、ほとんどのアプリはこれから恩恵を受けないようです-複雑さが増すだけでしょうか? 私はそうしないことを望みます。

しかし、この新しい粗粒度モジュールシステムを基盤となるモジュールシステムに完全に直交させる必要があるのか​​、それとも各トップレベルディレクトリとそれに含まれるすべてのEs6モジュールを暗黙的に作成できるのかどうか疑問に思います。粗粒度のNgModuleで構成されます。 おそらく、そのような規則駆動のメカニズムを現在のメカニズムの上に追加することができ、したがって、そのような規則に従うことをいとわないプロジェクトのNgModuleボイラープレートを削除することができます。

これが重要なポイントです。 ESModuleは、アプリケーションを正しく構造化すれば、アプリケーションを構造化するのに非常にうまく機能します。 たとえば、APIを上位レベルで再エクスポートするだけで、APIのトップレベルで深くネストされたエクスポートを簡単に利用できるようにすることができます。 また、一般的に、フレームワークにオプションの規則を追加することに賛成です。

私がangular2を初めて見たとき、私は次のように考えました。 内部モジュールをAngular1から削除し、代わりにESモジュールを使用しましたが、他の変更も歓迎されました(コンポーネント、タイプスクリプトなど)

しかし、これが安定するのを待つほど、重大な変更、ドキュメントの不足、不十分なエラーメッセージのために、私はうんざりします。 これで、このNgModuleが付属し、基本的に、角度1以降に変更した少なくとも1つのすばらしいことを元に戻します。

実際、Angular 2は、AngularJSの開発時には利用できなかった豊富な新しいWebテクノロジースタックを活用することになっていました。 それでも、Angular 2で行われた設計上の決定の多くは「Webコンポーネントをサポートする必要がある」という正当な理由がありますが、皮肉なことに、フレームワークはますます標準から逸脱しています。 現在、基準が悪い場合、基準から逸脱する正当な理由があります。

フレームワークがコアツールを十分に活用していないように感じます。 たとえば、TypeScript宣言は正確には慣用的ではなく、 anyany[]が散らばっています。 また、APIの使いやすさとツール性を向上させる強力な言語機能も無視します。 また、 export declare type Type = Functionのような忌まわしいものも含まれています。

興味深いことに、かなりの数の決定がダートに関連していることが判明したようです。 Dartは、ほとんどのAngularユーザーが気にするものではありません。 TypeScriptと比較して、タイプとは何か、およびそれらがどのように使用されるかについては、非常に異なる概念があります。 Dart <-> JavaScriptの相互運用機能は、多くの場合、初心者ではありません。

@aluanhaddad 、ダーツの実装は最近別のプロジェクトにフォークされたので、あなたの懸念のいくつかがすぐに改善されることを願っています。

この変更により、全体的なLOCとコンポーネントの依存関係のメンタルモデリングの両方の観点から、かなりの複雑さが加わりました。 私のコンポーネントファイルは少しきれいですが、明示的でインプレースの依存関係の定義が犠牲になり、冗長な感じの.moduleファイルが追加されています。

ボイラープレートを減らすことは良いことのように聞こえますが、やり過ぎになる可能性があると私は主張します。 さらに、この特定のボイラープレート削減の取り組みは、完全な削減ではなく、ボイラープレートの動きとしてより適切に説明されているようです。

Angularは、複雑なクイックスタートがより困難になる傾向にあると思います。 ツールチェーンのセットアップとファイルのリスト、および最もベアボーンアプリケーションでさえ理解しなければならないこと(ベストプラクティスに従う場合)に関しては、すでにかなりの対処が必要です。

@jbalbesありがとうございます、それは聞いて良かったです。

@radusuciuあなたは絶対に正しいです。これはボイラープレートの削減ではなく、そのボイラープレートをアプリケーションの別の領域に転送することです。 他の人がすでに言っているように、ここではコンポーネントレベルのスコープとNGModuleレベルのスコープの間に矛盾はありません。 必要なのは、アプリケーション固有の使用法とセマンティクスに基づいて、アプリケーションのティアを下げるために使用できるコンポーネント、ディレクティブ、パイプ、およびサービスを選択できる詳細なスコープです。

モジュールがアプリの作成者に疑わしい真の価値をさらに複雑にすることは、私には少し不思議ではありません。 これらは元のデザインの一部ではなく、他のものが壁にぶつかり、別の大きな変更を行わずに機能させることができなかったため(遅延読み込み、コンパイルなど)、追加されたのは遅いようです。

アプリ開発と「他の約束された機能を機能させる」へのすべての影響は、追加されたときに議題の上位にあったとは思いませんが、ますます大きなアプリがRC5に変換されるにつれて、それらはより明確になり始めています。

私は自分のアプリをモジュールに変換しようとさえしていません。おそらくRC4で死ぬでしょう。 非常に多くの部分を完全に作り直す必要があることを私は知っています、そしてそのすべての努力のために私が得るすべては、ミニファイ、確かにかなり基本的で基本的なものが壊れているので、さらに大きなランタイムバンドルで次の壊れた変更RCに近づくことです。 RCは、進行するにつれてより安定し、より完成したと感じるはずですが、そうではありません。

多くの人が雄弁に説明しているように、ギャング、NgModuleは苛立ちです。 しかし、実際にはそれほど大きなことではありません。 ここ(Oasis Digital / Angular Boot Camp)では、すでに多数の小さなものと、それほど小さくないものをRC5に更新しており、短時間で(長い間研究と理解を経て)完了しました。

みんなのアプリは違った影響を受けるでしょう。 さらに、アプリの提供に重点を置いている場合と、Angular 2のトレーニングとサポートも販売している場合では、Angular 2の解約と変更に対する態度が異なる可能性があると思います。私にとって、RC5にアップグレードするためのすべての作業は完全に死んで努力を無駄にする-それは実際にはマイナスの利益(より大きなバンドル)をもたらすので、正当化するのは難しいです。

RC6 *に到達するためにプラットフォームを5日間プッシュすることの裏側から考えを出そうと思っただけです(私たちは毎晩、RC6は執筆時点ではまだ技術的にドロップしていません)。 私の元のコメントはまだ有効ですが、このマイルストーンに到達したことには安心感があります。 最大の問題は、引き続き新しいルーティング構文を使用することです。空のpath: ''ルールが多すぎます。 (私は逸脱します)しかし、それはおそらく私たちが抽象化するものです。

夜間のNgModuleの場合、エラーメッセージが改善され、プロセス全体の操作が少し簡単になっていると言わざるを得ません。 コンポーネントとディレクティブは通常、問題を見つけるために大規模なNgModule依存関係ツリーをたどっていないほど十分な情報が正しく構成されていない場合に呼び出されます。 私たちが今直面している主な問題は、明らかなエラーメッセージがないページに機能がないことです。 これは通常、コンポーネントが正しく宣言またはインポート/エクスポートされなかったことが原因です。 少し注意が必要ですが、教育を受ければ簡単に対処できます。 テストは今や私たちの次のプッシュであり、水中で完全に死んでいます。 しかし、機能プッシュのように、最終的にはそこに到達します。

私たちは深呼吸をして、数日間何か他のことをして、それからそれを壊しました。 それが何であれ、私たちは次の乗り物のためにしっかりと保持しています! 小さなまたは大きな方法でこれによって影響を受けるすべての人に幸運を祈ります。 これについてAngularチームから何らかの対話があったら良かったでしょう。私たちが直面した最も困難な問題は、コミュニケーションの欠如でした。 先週のNgModulesの会議ノートのカードに何が入っているのかはまだわかりませんが、洞察は得られませんでした。 今週何が起こるか見てみましょう!

@SaltyDHこれは貴重なフィードバックだと思います。
コミュニケーションに関する苦情はあまり適切ではないと思います。

実装担当者は新しいリリースを作成し、ドキュメント担当者はドキュメントを更新します。
ドキュメントは、すでにコーディングされた後にのみドキュメント化できるため、通常、明らかな理由で多少遅れています。 ドキュメントの作成も大変で時間のかかる作業です。

リリースされた日に次のリリースに切り替える場合、またはナイトリーを使用する場合でも、すべてがまだ伝達されていないことを不平を言うのは少し不公平です。
Angularチームは、すべての場合にユーザーに問題を引き起こす可能性があるものを事前に知ることもできません。

Gitterと問題に関するサポートを提供するAngularチームのメンバーは常にいます。
また、コミュニケーションの負担は非常に非対称であり、数千人の開発者に対して数人のAngularチームメンバーがいることにも注意する必要があります。

これはマスタービルド(ほぼRC6)の方が簡単で、昨年以降の非推奨がようやくなくなることに完全に同意します。

@kylecordesマスターでの作業はどのように簡単になりますか?

NgModulesの設計ドキュメント(以前は設計ドキュメントが作成されたときにAppModulesと呼ばれていました)は、RC5がリリースされる1か月以上前にリリースされましたが、私はそれが来る準備ができていました。
さらに、NgModuleは新しい概念であるため、完全に取得して中規模から大規模のアプリに移行することは困難でした。
代わりに私がしたことは、最初にNgModulesのニュアンスとAngular2アプリケーションを設計するためのNgModulesでの考え方を完全に理解することです。 次に、NgModulesを適用して自己学習アプリを作成しました。
2番目のステップは、現在のアプリをモジュールで分割する方法を考えてから、それらをトップダウンで移行することです。 AppModuleから始めて、一度に1つのモジュールを作成します。 これは本当に役に立ち、最終的なアプリはより整理されたように見えます。
image

そして、はい、Gitterは、RC5がリリースされる前でさえ、NgModuleのヘルプを提供するのに本当に役立ちました。 RC5を投稿すると、ドキュメントやブログを利用して、より多くのことを学ぶことができます。

@zoechiこの議論をあまり狂わせずに、コメントを明確にしなければならないと感じています。 私はドキュメントをまったく参照していませんでした。私の理解のほとんどは、ここGitHubでコミットと問題を確認することから得られました。私はそれで問題ありません。 私の欲求不満は、この号のここでの表現の欠如から来ています。私たちは61のコメントとカウントをしています。 シンプルな「この号では、ここですべての人の懸念を認識しています。これがAngular 2にとって最善のアプローチであると確信しており、それが引き起こす困難を認識していますが、製品の将来にとってはより良いものです」。 Gitterは素晴らしいですが、Angular 2のさまざまな側面を理解しようとする人々の海で、個々のメッセージが失われることがよくあります。私はこのメディアを通じて連絡を取りましたが、タイムゾーンの違いやその他の優先順位のために、信頼できるフィードバックを得ることができませんでした。情報に基づいた決定を行うために使用できます。 助けになったのは、Angularポッドキャストhttps://devchat.tv/adv-in-angular/106-aia-angular2-rc5-and-beyondでのこの冒険でした。 これにより、NgModuleのアップグレードを進める自信がつきました。

ではごきげんよう。

皆様からのフィードバックに感謝します。返信を受け取るまでに時間がかかったことをお詫びします。先週は非常に忙しかったです(内部のGoogleアプリをNgModulesに移行しているため、リファクタリングの苦痛も感じています)

ここでいくつかの質問や誤解を解くことができるかどうか見てみましょう。

@NgModule()(および@Componentやその他のAngukarデコレータ)について最初に理解することは、これらは純粋にコンパイル時のコンストラクトであるということです。Angularコンパイラがアプリケーションの依存関係グラフを検出できるようにするために存在します。

デコレータが行うことの(簡略化された)バージョンは次のようになります。

//simplified Component decorator
export function Component(componentConfig){
  return function(componentClass){
    Reflect.defineMetadata('annotations', componentConfig, componentClass);
  }
}

装飾されたクラスの動作を変更または変更することはありません。メタデータを添付するだけです。 Angularはそのメタデータを使用して、アプリケーションを構築し、テンプレートをコンパイルします。

JiTモードでは、これは「ジャストインタイム」で発生します。bootstrapModuleを呼び出してから最初のコンポーネントレンダリングを行うまでの間に、AngularのコンパイラはReflectAPIを使用してクラスにアタッチされたメタデータを取得します。

let metadata = Reflect.getOwnMetadata('annotations', componentClass);

ただし、AoTモードでは、これは少し異なる動作をします。ビルド時に、デコレータをスキャンすることにより、ソースコードから同じメタデータを_静的に_(つまり、コードを実行せずに)抽出します。

これは、単一のコンポーネントをブートストラップする場合は問題なく機能しますが、複数のルートコンポーネントをブートストラップしたり、認証ステータスに基づいて異なるコンポーネントをブートストラップしたりするなど、より複雑なことを行っている開発者から多くのフィードバックを聞いています。

したがって、@ Componentデコレータはコンポーネントを静的に分析する機能を提供しましたが、 _Application_を確実に静的に分析する機能はありませんでした。

「アプリケーション」の傘下にあるもの

  • PLATFORM_DIRECTIVES / PIPES / PROVIDERS
  • 以前にbootstrap()に追加したもの
  • コンパイラレベルの設定
  • 複数のルートコンポーネント
  • サーバー側の使用法。

NgModulesは、静的に分析可能な一連の機能の概念を導入します。 興味深いのは、AoTコンパイルモードで、ルートモジュールを分析し、アプリケーション内の各モジュールのModuleFactoryを_生成_することです。これはモジュールのコンパイル済みバージョンであり、テンプレートで静的に参照するファクトリと「entryComponents」としてマーク

事前コンパイルに必要な情報をすでに抽出しているので、実際にデコレータをツリーシェイクすることができます(ngcはこれを最終的に自動的に処理します)-ルートモジュールからアプリケーションをバンドルするのではなく、開始します生成されたルートでModule_Factory_は、アプリケーションで実際に使用されるコードのみを含むため、モジュール性にペナルティを支払う必要はなく、rollupやwebpack2などのツールは_より効率的に_動作できます

次の返信でフォローする詳細...

@robwormaldこの種の背景情報に対する感謝の気持ちを絵文字に入れることはできません。

ありがとう!

NgModulesが解決する別の問題に遭遇しました:

DialogServiceなどを構築する場合を考えてみます。

歴史的に、あなたは次のようなことをするでしょう:

@Injectable()
export class MyDialogService {
  //inject the dynamic compiler 
  constructor(private componentResolver:ComponentResolver){}

  //accept a component and a viewContainerRef
  showDialog(component:Type, target:ViewContainerRef){
    //compile the component into a factory, async
    return this.componentResolver.resolveComponent(component)
      .then(componentFactory => {
         //dynamically insert the compiled componentFactory into the view:
        return target.createComponent(componentFactory);
      })
  }
}

...あなたが好きになる

myDialogService.showDialog(MyRandomDialogComponent).then(...)

ここで注意すべきこと-

  • JiTモードでのコンポーネントのコンパイルは、外部のtemplateUrlsとstyleUrlsのため、非同期である必要があります。
  • viewContainerは_componentFactory_を受け入れます-したがって、コードに問題があります。モードを切り替えるためにコードを書き直す必要があります(JiTとAoTの間)、またはコンポーネント挿入APIが非同期であると常に想定する必要があります。 これはダイアログの場合は問題ないかもしれませんが、複雑なUIを動的に構築している場合(ダッシュボードやグリッドビューなど)、大量の不要なPromiseスケジューリングが発生します。
  • サードパーティまたは共有サービス/コンポーネント(SharedDialogServiceなど)にも同じ問題があり、ComponentsまたはComponentFactoriesのいずれかを受け入れる必要があります

この問題は、動的コンポーネント挿入を実行している_any_アプリケーション(必ずしも遅延読み込みを意味するわけではありません)で発生します。ダイアログ、ルーターなどはすべて、セレクター(foo-bar)ではなくComponentTypes(クラス)と対話することを想定しています。

したがって、NgModuleデコレータのentryComponents配列にコンポーネントを追加すると、次のようになります。

@NgModule({
  declarations: [ MyRandomDialogComponent ],
  entryComponents: [ MyRandomDialogComponent ]  
})
export class MyApp {}

これがコンパイラに伝えるのは、「MyRandomDialogComponentとそのコンパイルされたMyRandomDialogComponentNgFactoryの間のマッピングを生成し」、_それが宣言されているNgModuleFactoryに格納する_ということです。

したがって、上記のdialogServiceのNgModule駆動バージョンは次のようになります。

@Injectable()
export class MyDialogService {
  //inject the component factory resolver 
  constructor(private componentFactoryResolver:ComponentFactoryResolver){}

  //accept a component and a viewContainerRef
  showDialog(component:Type, target:ViewContainerRef){
    //*retrieve* the componentFactory by component, sync
   let componentFactory = this.componentFactoryResolver.resolveComponentFactory(component)
   //add the componentFactory to the view, sync
   return target.createComponent(componentFactory);
  }
}

これで、entryModulesに追加したコンポーネントを同期的に取得して動的にビューに挿入できます。また、使用しているモードに応じてコードを変更する必要はなく、サードパーティ/共有ライブラリでコンパイルについて心配する必要もありません。論理。

説明ありがとうございます@robwormald

1つの質問は、指令/パイプ宣言を削除する必要があるかどうかです。 NgModuleと共存できない理由はありますか?

私を含む人々は、「ブロックの新しい子供」NgModuleやその誤解に不満を感じているように感じますが、多くの人々と「うまく機能している」ように見えることを行う「古い方法」が特にこの後期RCステージでは、強制的に削除されました。 これは、私があまり見たことがない、まだ直接対処されていないNgModule自体に対する抵抗との重要な違いだと思います。

また、directive / pipe宣言を削除するためのプルリクエストがアップしていることもわかります(https://github.com/angular/angular/pull/10912)-何かが設定される前に、この時点で応答を取得できることを期待しています結石。

前もって感謝します。 Angularは間違いなく一緒に仕事をするのが楽しいものであり、この1年間のチームの懸命な努力に感謝しています+

ここには「グローバルスコープ」に関するコメントがいくつかあります。これは、コンパイラとモジュールの仕組みを誤解しています(これは完全に理解できますが、これは複雑なことです)。

アプリケーション全体を単一のNgModuleにダンプすることは、アプリケーション全体の状態を$ rootScopeにダンプすることがAngular1で「正常」であったように、「正常」です(読み取り:動作しますが、アプリケーションの設計が不十分です)。

Angular 1では、すべてが単一のインジェクターバッグにダンプされたため、モジュールをアプリケーションに取り込むと、アプリケーション全体が多かれ少なかれ「汚染」されました。

Angular2では、NgModuesには、汚染のない合成を可能にする非常に強力なスコープメカニズムがいくつかあります。 ここでも、コンパイラに戻ります。

Angularがアプリケーションをトラバースしてコンパイルしているとき、遭遇した各コンポーネントは_宣言されたコンテキストでコンパイルされます_

たとえば、アプリケーション全体で共有したい機能を備えたSharedModuleがあるとします。

@Component({
  selector: 'shared-component-one',
  template: `
    <div>Shared Component One</div>
    <shared-component-two>
  `
})
export class SharedComponentOne {}

@Component({
  selector: 'shared-component-two',
  template: `
    <div>Shared Component Two</div>
  `
})
export class SharedComponentTwo {}

@NgModule({
  declarations: [ SharedComponentOne, SharedComponentTwo ],
  exports: [ SharedComponentOne ]
})
export class SharedModule {}

SharedComponentOneとSharedComponentTwoはどちらもSharedModuleで_declared_されています-宣言は_ownership_を意味します-したがって、これらのコンポーネントは両方ともSharedModuleによって所有されます。 ただし、_only_SharedComponentOneはモジュールから_エクスポート_されます-SharedComponentTwoはSharedModuleに_private_のままです。

SharedModuleを持ち込んで、次のように別のモジュールで使用する場合:

@Component({
  selector: 'some-component',
  template: `
    <div>hello from some component</div>
    <shared-component-one></shared-component-one>
  `
})
export class SomeComponent {}

@NgModule({
  imports: [ SharedModule ],
  declarations: [ SomeComponent ]
})
export class SomeModule {}

...コンパイラがSomeComponentのコンパイルを開始すると、 shared-component-oneセレクタが検出され、$ SharedModuleSharedComponentOneをエクスポートする)がSomeModuleにインポートされるためです。

興味深いことに、コンパイラが実際にSharedComponentOneをコンパイルするとき、SharedModuleの「内部」でコンパイルします。これにより、SharedModule内で、外部に公開されていないものを使用できるようになります。

これは、Component.directivesでの作業方法と非常によく似ており、この場合は同じです。

ただし、タブ機能のようなものがあるかどうかを検討してください。

@Component({
  selector: 'my-tabs',
  template: '...'
})
export class TabsComponent {}

@Component({
  selector: 'my-tab',
  template: '...'
})
export class TabComponent {}

これらのコンポーネントは両方ともトップレベルであり、依存する階層関係はありません。 これらは、やっている人々の一種のコンベンションの爆発につながりました

export const TAB_DIRECTIVES = [ TabsComponent, TabComponent ]

より複雑なタブ機能には、タブの複数のインスタンスを管理するサービスがある可能性があるため、その場合も処理する必要があります...

export const TAB_PROVIDERS = [ ... ]

そしてそれを使用することは、あなたがエクスポートおよびインポートしなければならないすべてのものを覚えておくための練習になります...

import {TAB_DIRECTIVES, TAB_PROVIDERS}

そして、それらすべてを、使用したい_どこでも_適切な場所に提供します。 また、この時点で、機能に必要なものをすべてインポートするのを忘れて、奇妙なサイレントエラーが発生したり、コンポーネントが必要なコンテキストなしでコンパイルされたりすることも非常に簡単です。

NgModuleを使用すると、それらを1つのユニットにパッケージ化して、アプリケーションに渡し、必要に応じてインポートすることができます。

マテリアルデザインのように、複数のモジュールに多数の機能が分散している可能性があるライブラリの場合、同じインポート/エクスポートセマンティクスを活用して、さらに移植性を高めることができます。

@NgModule({
  exports: [ TabsModule, NavbarModule ]
})
export class MaterialSharedModule {}

その単一のモジュールをプルすると、すべてのアプリケーションでコンポーネントを使用できるようになります。また、AoTの時点では、使用するコンポーネントのみが生成されたコードにインポートされます。

Component.directives / pipesを削除した理由については、両方向から多くのフィードバックが寄せられています。 同じことを達成するための2つの方法があることは一般的に悪いパターンであると感じているため、一般的に人々がより少ないコードを記述できるようにすることを選択しました。以前にComponent.directivesによって提供された明示的なスコープが必要な場合は、モジュールレベルでのスコープ。

RC5では、Component.directivesを「グローバル」スコープに自動で巻き上げるようなものを実行しました。 これは移行をスムーズにするための試みであり、ほとんどの人にとっては機能しましたが、新旧が混在する動作により、いくつかの奇妙なエラーや動作が発生し、イライラする一方で一時的なものでした。 これはRC6でなくなります(そしてエラーメッセージが改善されました)

なぜこれがゲームの後半に変わったのかについては、お詫びするしかありません。 土壇場で変更を加えるのは、他の誰よりも好きではありません。 結局のところ、私たちは文字通り、これまでフロントエンドの土地で行われたことのない方法でフレームワークを構築しているため、予期しない問題や設計上の問題が発生します。 これはそのようなケースの1つであり、決定を下す前にコアチーム間で強力な議論と調査が行われました。 繰り返しになりますが、ご迷惑をおかけして申し訳ありませんが、最終的な結果は_applications_を構築するためのはるかに優れた方法であると確信しています。そのため、私たち全員がここにいます。

皆さんの忍耐に感謝します。 ここで取り上げていない他の質問がある場合は、これを開いたままにしておきます。

ロブ

よくできました、 @ robwormald

さらにいくつかの所見を追加したいと思います。

プロバイダー

Robは、_declarations _、_ imports _、および_exports_に焦点を合わせました。 モジュール_プロバイダー_は異なります。

@Component.providersが生きています! @Component.directives@Component.pipesのみがなくなります。

@NgModules.providers@Component.providersの両方を使用できます。 それらには異なる目的があります:

a) @NgModules.providersは、「メイン」インジェクター(熱心にロードされたモジュール用のアプリルートインジェクター)にプロバイダーを追加することにより、アプリケーションを_拡張します_。 これは、 RouterModuleがルーティングサービスを提供しなくてもアプリに追加する方法です。

b)コンポーネントインスタンス(およびそのコンポーネントサブツリー)のスコープ内での@Component.providers _ encapsulates_サービスプロビジョニング。

どちらのアプローチも異なるニーズを満たします。

私の一般的なアドバイス:_今日@Componentにプロバイダーがある場合は、そのままにしておきます_

機能モジュール

これらは、アプリを整理するための強力な方法です。 Angular Moduleの章には、モノリシックAngularModuleから機能モジュールへのリファクタリングに関する短いセクションがあります。 それはとても簡単です(少なくとも私にとっては何度かやったことがあります)。

アプリで自然な縫い目を探します。 私は気が狂うことはありません。 すべてのコンポーネントをモジュール化するわけではありません。

マテリアルデザインがそうしているように見える理由は、彼らが私たちが望むものをきめ細かく使いやすくしようとしているからです。

彼らは単にすべてを再エクスポートするキッチンシンクモジュールを持っているでしょう。 それをインポートして実行することができます。 ただし、自分のアプリを調整する場合は、必要なMDパーツのみをエクスポートする同様の_再エクスポートモジュール_を作成します。

これは、どの図書館ベンダーも従うことができるパターンであり、承認されたガジェットの自社承認の「キット」をまとめた企業では理にかなっているかもしれません。

宣言の依存関係の検出

コンパイラーは、何かが足りないときに通知するという、はるかに優れた仕事をします。 推奨される方法に従い、コンポーネントセレクター名を_常に常にハイフンでつなぐ_場合、コンパイラーは、宣言されていないコンポーネントがある場合に通知します。 また、宣言されていない/認識されていないデータバインディングとディレクティブを取得します。

以前のRC5からの移行は、喪失感を助長します。 以前のdirectives #$リストとpipesリストで依存関係を見つけるという面倒な作業を行う必要があります。 そして、重複排除する必要があります。 これは、端に住むことの本質的な不快感です。

RCはこれほど変更すべきではありません

うん。 あなたはそれについてチームから議論を得ることができません。 意図的ではありませんでした。 NgModuleが必要だとわかっていたら、ベータ版で入手できたはずです。

しかし、IMOは、RCがどうあるべきかという概念に惜しみなく従い、間違った製品を納品するよりも、適切な製品を出荷する方がよいでしょう。 また...そして言うのはそれほど快適ではありません...しかし、最近他のいくつかの主要なソフトウェア会社を見ているなら、あなたは「リリース候補」の同等に柔軟な概念に気づいたかもしれません。 それは私たちの業界が何らかの理由で進む方法です。

私は今、いくつかのアプリを変換し、他の人がそうするのを手伝いました。 「_彼らは私のチーズを(再び)_」フェーズを過ぎると、それはかなり機械的な移行であり、誰もが彼らがより良い場所にいると思っているようです。 たぶん彼らは私に親切なだけです。 OTOH、私はそんなに素敵な人たちとたむろしません;-)

(また、re:名前)
私たちは名前を自転車で流して死にました。 それらは当初AppModulesと呼ばれていました(コンポーネントよりも高いレベルの「アプリ」を表すため)が、十分に広い用語ではありませんでした。 パッケージ、バンドル、バレル、グロブなど。

ESモジュールの代わりではないことを覚えておいてください-ツリーシェイクとESモジュールがすべてのAngular開発者にとってより良く機能するようにする拡張であり、意味的には、ESモジュールの動作(インポート、エクスポート、宣言)に似ています

ですから、ネーミングは難しいです。 NgModuleです。

私たちは2.0.0のAPIを完了しているので、リリース後の数か月間、どのパターンが開発され、どこで2.1のより良い推論を行うことができるかを監視します。

非常に洞察に満ちたコメントをありがとう@ robwormald @ wardbell 。 私にとって最大の安堵は

「私たちは2.0.0のAPIを完成させているので、リリース後数か月にわたって、どのパターンが開発され、2.1のどこで砂糖を使ってより良い推論を行うことができるかを監視します。」

これは数週間前にすでに聞いたことがありますが、現在は特にNgModulesとこのフィードバックのすべてのコンテキストで使用されています。 それは私が理事会に行って言う必要がある自信です。 これで、アプリケーションの構築が完了しました。 また、このマイルストーンに到達したng2チーム全体とコミュニティにもお祝いの言葉を述べたいと思います。 これからのエキサイティングな時代。

私はあなたが@SaltyDHと言うことができると正直に信じています。 Angular2チャーンは終了しました。

これは、Angular2が進化しているという意味ではありません。 将来のリリースがあります。 しかし、2.0につながるチャーンは...終わりです!

誠実さと明確なユースケースに感謝します。 それは本当に役立ちます。

NgModuleのAPIでの命名と複製について簡単に考えてみてください。これは、少し面倒だと思います。

IMOこれ:

@NgModule({
  declarations: [ SharedComponentOne, SharedComponentTwo ],
  exports: [ SharedComponentOne ]
})
export class SharedModule {}

...次のように、より明確で簡潔にすることができます。

@NgModule({
  private: [ SharedComponentTwo ],
  public: [ SharedComponentOne ]
})
export class SharedModule {}

1)ネーミングへのWRT(パブリックおよびプライベートvs宣言およびエクスポート)、それは本質的に上記の@robwormaldの方法であり、他の多くの人がそれを説明していると確信しています

2)(命名を無視)なぜSharedComponentOneを繰り返す必要があるのですか? 確かに、それが「輸出」であるならば、それは「宣言」でなければならないと言うことができるので、それはそのように脱糖されることができますか?

非常に主観的なものにちょうど私の2セント😄-詳細な説明にもう一度感謝します!

@ robwormald @ wardbell詳細な説明をありがとう。

そして、このスレッドで前に述べたように、 NgModulesは私たちがよりよく整理するのに役立ちます。 最近の例は、テンプレート駆動型フォームのバリデーターディレクティブの作成です。 RC5より前では、フォームを作成するコンポーネントに各ディレクティブをインポートする必要がありました。 これで、 VaildatorModuleにパッケージ化し、必要に応じてモジュールをインポートします。 後で追加するバリデーターは、 ValidatorModuleをインポートしたモジュールで自動的に利用できます。 依存関係を気にせずにテンプレートを更新する必要があります。

@JamesHenry declarationsimports 、およびexportsは、 importexport 、およびdeclareのように、NgModuleをES6モジュールと一致させるために使用されます。 ES6モジュールの
私は砂糖漬けに同意します。エクスポートされたものは、魔法のように自動で宣言に砂糖を取り除くことができます。

@JamesHenry

1)、メンタルモデルはesモジュールの動作に近いため(少なくともスコープの観点から)、インポート/エクスポートに固執しました-モジュール内で物事を宣言し、他のモジュールから物事をインポートし、物事をエクスポートして利用できるようにしますその他。

2) if it is an "export" it must be a declaration, so it could just be desugared that way? ->これは、上記のMaterialModuleの例のように、ngModuleを使用して再エクスポートするまで機能します-ngModuleを使用して、別のモジュールで宣言されたものを再エクスポートする場合がたくさんあります。その後、推論は一種の崩壊します。

@robwormald素晴らしいコメント! 間違いなくブログ投稿に値する。

現在@NgModuleを使用するダイアログライブラリがあり、ユーザーがカスタムコンポーネントを追加しようとして、 entryComponentsに登録するのを忘れているため、苦労していることがわかります。これは明らかに十分ではありませんが、高度な機能なので理解できます...

時間とともに沈むと確信しています

@shlomiassafありがとう!

あなたのような場合についても言及する必要があります:

角度のルーターを使用する場合、ルーターがentryComponentsの定義そのものであるにもかかわらず、宣言とルート構成にコンポーネントを追加しますが、entryComponentsには_not_することに注意してください。 (覚えておいてください-entryComponent ===セレクターではなく、クラスで参照したいもの)

どのライブラリでも利用できるクールなトリックがあります- ANALYZE_FOR_ENTRY_COMPONENTSと呼ばれる魔法のトークンがあります-https://github.com/angular/angular/blob/master/modules/%40angular/router/src/を参照してください

したがって、動的に挿入されたコンポーネントを処理するライブラリの場合、次のようにすることができます。

@NgModule({
  providers: [ DialogService ]
})
export class DialogModule {
  static withComponents(componentList): NgModuleWithProviders {
    return {
      ngModule: DialogModule,
      providers : [
         { provide: ANALYZE_FOR_ENTRY_COMPONENTS, useValue: componentList, multi: true }
      ]
     }
  }
}

のように使用

@NgModule({
  declarations: [ MyConfirmDialog, MyQuestionDialog ],
  imports: [
    DialogModule.withComponents([ MyConfirmDialog, MyQuestionDialog ])
  ]
})
export class MyAppModule {}

あなたのユースケースではうまくいくかもしれませんが、うまくいかないかもしれません。

@JamesHenry declarationsprivateと混同されないことが非常に重要です。 あなたは_このモジュールがこのコンポーネントを宣言している_と言っています。 あなたは公的または私的について何の発言もしていません。 あなたは所有権を主張しています。

それは本当にES6モジュールで起こることのようです。 ファイル内で定義したものはすべて、そのファイルで定義されたモジュールに「属します」。 公開されているかどうかは、キーワードexportの使用によって異なります。

また、ES6モジュールと同様に、インポートしたものを_再エクスポート_できます。

declarationsは、すべてのコンポーネント、ディレクティブ、パイプを同じ物理ファイルに物理的に配置する必要がないようにする「トリック」と考えるのが好きです(意図した場合はES6モジュールで行う必要があります)。これらのクラスはすべて同じES6モジュールに属します)。

したがって、私にとって、 declarationsは、これらのファイルを1つのひどい大きなファイルに貼り付ける代わりになります。 それはとにかく_my_メンタルモデルです。

注意すべきことの1つは、モジュールのコンテキストにおけるプロバイダーとコンポーネントの論理的な違いです。

プロバイダーとコンポーネントは同じ場所( NgModuleMetadataType )で宣言されるため、開発者はプロバイダーがコンポーネントのように動作することを直感的に感じるかもしれません...モジュール内のプロバイダーがそのモジュールのインスタンスになると考えています。 。

プロバイダーはDIによって管理されるため、これはもちろん真実ではなく、実際にはアプリケーションレベルです。
モジュール内のコンポーネントは、エクスポートされない場合はプライベートであり、混乱を招く可能性があります。

私はモジュールの概念が大好きです。IMOのAPIの唯一の問題は、プロバイダーとコンポーネントをモジュール内の同じ場所で宣言することです...新規参入者にとっては理解するのが難しいことです。

@wardbellありがとうワードそれは本当に本当に素晴らしいです! これが議論の中で出てきたので明確にするために、Angular 2はAPIが完全であると言うとき、ここで話している名前空間はどれですか? @ angle / ???

@robwormaldありがとう! 素晴らしいヒント!!!
砂糖風味のもの! 実装します。

私はGoogleの従業員ではなく、おそらくGoogleの従業員は言うことができませんでした。 私は自分の2つの目でしか見ているものを報告できません@angular/ライブラリのセット全体で非常に深刻なAPIフリーズです。

リリースを保持することを正当化するのに十分または十分に深くなかったので、棚に座っている良いアイデアがあります。 そうあるべきです。 良いアイデアは止まることはありません。 しかし、_これはあなたのAngular2.0_です。

現在から「最終版」までの間に廃止予定のAPIを削除することをお約束します。 それには微調整があります...誰もがマスターを見ればわかるように。 終わったような気がします。

@wardbell私はあなたが輸出について言うことをエコーし​​ます。
index.tsはかつてで埋められていました

export * from 'a.component'
export * from 'b.component'
export * from 'c.component'
export * from 'p.directive'
export * from 'x.service'
export * from 'z.pipe'

現在はexport * from my.moduleに削減されています
残りのすべてのものをきれいにNgModuleエクスポートに配置します
exports: [ AComponent, BComponent, CComponent, PDirective ]など

@wardbell @NgModules.providers@NgModules.rootProvidersまたは@NgModules.appProviders $でなければならなかったと思います。

プロバイダーのコンテキストを明確に説明していると思います。

@shlomiassafそれは誤解を招くでしょう。 @NgModules.providersの効果は、熱心なモジュールと怠惰なモジュールでは異なります。 遅延ロードされたモジュールは、独自の子インジェクターを取得します。つまり、_root_インジェクターではなく、_子_インジェクターに_それらのプロバイダー_が追加されます。 したがって、レイジーがレイジーをロードした場合も同様です。

たぶん別の名前があったかもしれません。 あなたは_それ_がどうなるか知っています。 しかし、 rootProvidersは、私が今与えた理由のために改善されなかったでしょう。

@wardbellは同意し、そのシナリオについては考えませんでした。

徹底的な返信とコミュニケーションが非常に高く評価されているという感情を追加したかっただけです。 これが実際にrcからfinalまでの成長痛の最後である場合、私たちはレースに出かけます。 ありがとう!

他の人が述べているように、チームからのフィードバックは高く評価されています。 ただし、開発のこの段階でのこの種の変更は、基本的な設計エラーを示唆しています。
正直に言うと、私たちは皆、このような間違いを犯しているので、判断する価値はありませんが、間違いを犯すと、謙虚になり、その後、より慎重になることを願っています。 アナグラーチームに同じ効果があるという印象はありません。

宣言は、すべてのコンポーネント、ディレクティブ、およびパイプを同じ物理ファイルに物理的に配置する必要がないようにする「トリック」と考えるのが好きです(これらのクラスをすべて意図した場合、ES6モジュールで行う必要があります)。同じES6モジュールに属します)。

したがって、私にとって、宣言は、これらのファイルを1つのひどい大きなファイルに貼り付ける代わりになります。 それはとにかく私のメンタルモデルです。

@wardbell基本的なものが欠けているかもしれませんが、 NgModule.declarationsの使用が、ESModuleのすべてをインポートするのとは根本的に異なるのかわかりませんが、一部を再エクスポートするだけです。 皮肉なことに、ESModuleの主な制限は、論理モジュールではなく、物理モジュールの概念のみを提供することです。 NgModuleがそれをどのように改善するかわかりません。 これは単なる異なる集約構文ですが、意味のある程度まで抽象化のレベルを上げることはありません。

また、NgModulesは主要な問題に完全に対処できません。

Function[]パターン全体は、すべての間違った方法で不透明です。 発見可能性をゼロにします。 ソースを読み取って、プロバイダーの配列に何があるかを判断する必要があります。 同じことがNgModule.exportsにも当てはまります。

しかし、IMOは、RCがどうあるべきかという概念に惜しみなく従い、間違った製品を納品するよりも、適切な製品を出荷する方がよいでしょう。 また...そして言うのはそれほど快適ではありません...しかし、最近他のいくつかの主要なソフトウェア会社を見ているなら、あなたは「リリース候補」の同等に柔軟な概念に気づいたかもしれません。 それは私たちの業界が何らかの理由で進む方法です。

@wardbell私にとってRCの最大の不満は、ng-confとgoogle i / oのためにベータ版がRCにプッシュされたという印象です。 進歩を遂げるには、理由を明確に示す必要があります。それは_マーケティング_であり、技術者として、これらの柔軟な成熟概念の傾向と戦う必要があります。 谷で人気のある自動車メーカーを知っているかもしれません。そこでは、製品のベータ版を販売するのが正しいかどうかについて議論されています。 誇張したくはありませんが、技術者として、それが私たちの業界のやり方であるかどうかを話さなければなりません。それは間違った方向に進んでいるからです。

私はngmoduleアプローチが好きですが、質問があります@robwormald

コンポーネント、ディレクティブ、パイプのない共有サービスがあります。 サービス( forRoot )のみがあり、すべてのビジネスモデルクラスが含まれています。 app.moduleServerApiModule.forRoot() $をインポートするため、アプリケーション全体でサービスを利用できます。 サービスとビジネスモデルクラスを使用する機能モジュールは、この共有モジュールをインポートする必要がありますか? 技術的には必要ありません(エラーなし)が、セマンティックの観点からは意味があります(エラーもありません)。 そのようなモジュールで何をすべきでしょうか? それらをインポートするかどうか? 私は個人的に2番目の可能性が好きです。「ねえ、私は機能モジュールであり、このサービスが必要であり、このビジネスモデルクラスが必要です」と書かれているからです。

答えてくれてありがとう!

そのため、ライブラリ/モジュラーアプリケーションライブラリとngModuleの問題を感じることができます。

しかし、何度も言われているように、2つの可能な方法を混ぜないでください。 それは混乱を招くでしょう。

したがって、正しいアプローチは、コンポーネントごとにngModuleを宣言することです。
しかし、これによりすべてのコンポーネントのボイラーコーダーが大幅に増えるため、この方法は大規模でも機能しません。

したがって、コンポーネントやモジュールのようなマテリアルを宣言することを避けるために、多かれ少なかれ砂糖であるComponentModuleと呼ばれる新しいデコレータを追加しないでください。

このように? コンポーネントが表示された場合。 私はそれがngModuleの一部でなければならないことを知っています。 多くのコンポーネントがそれらをバンドルする場合がある場合は、NgModuleを使用できます。 「古いコンポーネント」のようなスタンドアロンコンポーネントが必要な場合は、ComponentModuleを使用し、すべての依存関係を知っています。他のモジュールのモジュール依存関係になる可能性がありますが、それらの一部ではありません。

@nathraQ正しいアプローチがすべてのコンポーネントにNgModuleを使用することであり、そうなる可能性がある場合、NgModuleは導入されるべきではなく、コンポーネントは拡張されたばかりであるはずです。 ボイラープレートに関しては、Angular 2は非常に重いため、現時点ではほとんど問題になりません。

独自のモジュールシステムを持たない多くのフレームワークは、構造のレイアウトと可視性の標準パターンを確立するために、規則を非常にうまく使用しています。 賢い人はかつて、事後に慣習を定義することはできないと言いました。 彼らは最初からそこにいる必要があるということです。 私はこの主張に懐疑的でしたが、この大失敗は彼が正しかったことを証明しています。

@aluanhaddad申し訳ありませんが同意しません。 カスタム依存関係管理(このスレッドのスターターなど)を備えたangular 1.xの1つのモジュールのみのユースケースがありましたが、コントローラー、ディレクティブ、およびサービスのセットをバンドルするモジュールのユースケースもありました。

どちらも便利です。 今、私たちはそれを誰にとっても理解できるように統合する方法を理解する必要があります

うわー、それは長い間読んだ:smile:

新しい変更の長所と短所はわかりますが、Angular1で問題が発生した1つのシナリオについて考えさせられました。

@wardbell @ robwormald-

SharedModuleパターンを使用し、2つのサードパーティライブラリ(ui-bootsrapとangular-strapのどちらか?)をインポートする場合、どちらもコンポーネントに同じセレクターを使用します。たとえば、 my-selectbox

両方をインポートしようとするとエラーが発生しますか? 正しい?

ここで読んだ解決策の1つは、カスタムモジュールでライブラリの1つを再エクスポートすることです。
しかし、それは、ライブラリがアップグレードするたびにラッパーモジュールを更新し続ける必要があることを意味しますか?

また、同じ名前の独自のコンポーネントセレクターがある場合もあります(複数回発生する可能性のある大きなプロジェクトでは)

この問題に対する推奨される解決策はありますか? それとも「ラッパーモジュール」ですか?
(セレクターのプレフィックスの使用に戻らないことを願っています。それは面白くありませんでした)

前もって感謝します!

プロジェクトの規模に関係なく、名前空間、または名前空間と呼ばれる接頭辞は、一般的には良い考えです。 はい、小規模なプロジェクトでは簡単かもしれませんが、サードパーティのモジュールが関係するようになるとすぐに、それはほぼ要件になると思います。少なくとも、他のモジュールが更新されても衝突が発生しないことを知って安心できます。 、だけでなく、開発者は、依存関係ツリーに従わなくても、各モジュールに属するものを簡単に識別できます。

@nathraQこれらのパターンはすべて、ECMAScriptモジュールを使用して実現できます。 NgModuleの導入は私たちをどこにも連れて行かず、AngularMaterialのようなライブラリが以前に提供されたカプセル化を維持するためだけにコンポーネントをNgModulesに変えているという事実はちょうどポイントを証明します。

@aluanhaddad NgModulesは、ESモジュールとは非常に異なることを行おうとしており、コンポーネントのカプセル化も置き換えていません。つまり、ESモジュールとコンポーネントの両方がコアの責任を変更していません。 NgModulesは、アプリケーション全体のアーキテクチャを説明するための媒体です。これにより、Angularは意図をよりよく理解し、それに応じて最適化することができます。これにより、アプリケーションの特定の部分を事前にコンパイルしたり、サーバーから動的に解決されたモジュールを提供したりできます。 ESモジュールでは実現できません。 同じ理由で、コンポーネントごとに1つのNgModuleは、従うべき経験則ではありません。

確かに、単純なアプリケーションはこれらの利点からそれほど恩恵を受けないかもしれませんが、そのような場合、NgModulesはとにかく「煩わしさ」が少ないはずです。

@ emilio-martinez、@ aluanhaddadが書いたように、ES6と「古いAn​​gular 2 Way」は、必要な名前空間を提供してくれました。

私はAngular1で非常に大規模なプロジェクトに取り組んできましたが、セレクターの名前mb-product-listで、大規模なプロジェクトの場合は他のプロジェクトと非常にすばやく衝突する可能性があります(5人以上の開発者のチームでも)。

より多くの名前空間でそれを解決しようとすると、最終的にはmb-somefeature-product-listになり、テンプレートが汚れて見えます。

directivesメタデータのおかげで、ng2で解決されたのを見てとてもうれしかったです。
npmで好きなパッケージをインストールし、コンポーネントごとに必要なものだけをインポートできます。

ngModulesには確かに利点があり、チャンクを非同期でロードするのに役立ち、インポートの書き込みを減らして生産性を向上させるのにも役立ちます。

ただし、 SharedModuleパターンを使用すると、ng1の場合と同様に、グローバル名前空間が導入されます。

少なくともプロバイダーでは、ファイルの場所であるES6トークンによって名前空間が指定されます。

コンポーネントの場合、セレクターがあるため、同じセレクターを持つ2つのコンポーネントがあると悲鳴を上げます。

サードパーティまたはローカル共有コンポーネントとの衝突のユースケース用に特別な名前空間を構成する簡単な方法があればいいのにと思います。

「セレクターオーバーライド」のようなもの。

それが私が求めていたものです

詳細な洞察を提供してくれた@robwormaldに感謝しますが、私のような初心者からの1つのことです(ほとんどの場合、私はバックエンド開発者です)。 私はAngular2とtypescriptを学んでいます。 したがって、ES6モジュールの概念は私には少しぼやけています
複雑なアプリケーション構造があります。 その分析アプリでは、私のコンポーネント数はほぼ60です。
そして、私はそれがRC4の下でうまく構築されていると思います。 loginを除いて、routernはコンポーネント全体を再作成するため、ルーティングは使用しませんでした。 そのため、タブベースのアプリとして計画しています.2つのメインタブがあります(1.分析2.ダッシュボード)。
[分析]タブには複数のタブがあり、それぞれに単一の分析があります。 ダッシュボードにも
複数のタブがありますが、各タブは下に保存された複数の分析で構成されます
分析セクション。 したがって、複数のタブから前後に移動します(ダッシュボードと分析の両方の下)
また、[ダッシュボード]タブと[分析]タブを切り替えると、ルーティングが機能しないと感じます
私たちの目的(私が何か馬鹿げたことを言っているなら私を訂正してください)。
これで、RC5NgModuleはアプリケーションを壊します。 私たちは本当に方法を知りません
アプリケーションを再設計します。 アプリケーションでAoTコンパイルを実際に使用できますか? そうじゃない
AoT全体がルーティングに基づいていますか?

@shairez NgModulesは、まさにこの種の名前空間を提供します。 これをもう少し明確にしてみましょう...

ここで理解する重要なことは、コンポーネントが、多かれ少なかれ、宣言されたモジュールの「内部」でコンパイルされることです。例については、 https://plnkr.co/edit/9w10b1Y8Bjr5DDIxOwnC?p = previewを参照してください。

2つの競合するセレクター( my-generic-selector )があることに注意してください。各機能モジュールはそのうちの1つをインポートし、「グローバル」ネームスペースを汚染することなく、そのモジュールの内部で使用できます。

のように使用

<my-app>
  <!-- belongs to FeatureModuleOne -->
  <feature-one></feature-one>
  <!-- belongs to FeatureModuleTwo -->
  <feature-two></feature-two>
</my-app>

に拡大

<my-app>
  <!-- belongs to FeatureModuleOne -->
  <feature-one>
    <!-- the generic imported in FeatureModuleOne -->
     <my-generic-selector></my-generic-selector>
  </feature-one>
  <!-- belongs to FeatureModuleTwo -->
  <feature-two>
    <!-- the generic imported in FeatureModuleTwo -->
    <my-generic-selector></my-generic-selector>
  </feature-two>
</my-app>

コンパイラが機能1と機能2をコンパイルするとき、それらが属するモジュールのコンテキストでコンパイルするため、競合は発生しません。これにより、グローバルスコープの汚染が回避されます。

@robwormald確かに、それは素晴らしく、その意味でAngular1よりも優れています。

私が書いたユースケースは、ドキュメントで提案されているように、グローバルSharedModuleを使用するパターンを参照していました。

GenericSelectorFeatureOneGenericSelectorFeatureTwoの両方をSharedModule内で宣言しようとすると、エラーが発生しますか?

または、 SharedModuleに便利な共通コンポーネントがたくさんあり、それをすべての機能モジュールにインポートしたい場合。

機能モジュールに衝突セレクターがある場合、または一部のサードパーティにSharedModuleにエクスポートされた既存のライブラリの1つとの衝突セレクターがある場合、エラーが発生しますか?

@shairezほとんどのアプリケーションは「SharedModules」の数になり、衝突の可能性は低いと思います。モジュールは安価なので、たくさん持っていても大きなコストはかかりません。

ドキュメントを改善する方法についてアイデアがあれば、PRを歓迎します。

それが私が探していた答えであるおかげで、私はそれをテストします。

モジュールを書く新しい方法でこれを解決する方法についてはまだ良いアイデアがありません。そのため、ここで質問しましたが、複数の共有モジュールソリューションをテストしたら、 @と話し合うための資料が増えます。

助けてくれてありがとう@robwormald

https://angular.ioで入手可能な最新のドキュメントから、 NgModuleが正しく構成されていない場合に簡単に発生する可能性のある、アンチパターンとバグに関する多くの警告があります。 例えば

共有モジュールでアプリ全体のシングルトンプロバイダーを指定しないでください。 その共有モジュールをインポートする遅延ロードされたモジュールは、サービスの独自のコピーを作成します。

それはかなり厄介です。 _最初に機能させ、次に高速化する_という実証済みの真のアプローチに従う場合、アプリケーションまたはライブラリが拡張するにつれて、経験的なメトリックとこれらのモジュールの出現構造に基づいて、どのモジュールが熱心にまたは遅延してロードされるかを調整する必要があります。 基本的に、モジュールが遅延または熱心にロードされるかどうかをモジュールが気にする必要があるのはなぜですか?

別の、一見もっと深刻な問題は、ドキュメントの次のセクションを並置することから発生します

モジュールに、すべてのHttpリクエストに特別なヘッダーを追加するカスタマイズされたHttpBackendが必要であるとします。 アプリケーションの他の場所にある別のモジュールもHttpBackendをカスタマイズするか、単にHttpModuleをインポートする場合、このモジュールのHttpBackendプロバイダーをオーバーライドして、特別なヘッダーを失う可能性があります。 サーバーは、このモジュールからのhttpリクエストを拒否します。
アプリケーションルートモジュールであるAppModuleにのみHttpModuleをインポートすることにより、この問題を回避します。

クラスとモジュールを再エクスポートできますか?
絶対!
モジュールは、他のモジュールからクラスを選択的に集約し、統合された便利なモジュールに再エクスポートするための優れた方法です。
モジュールは、モジュール全体を再エクスポートできます。これにより、エクスポートされたすべてのクラスが効果的に再エクスポートされます。 Angular独自のBrowserModuleは、次のようないくつかのモジュールをエクスポートします。
エクスポート:[CommonModule、ApplicationModule]
モジュールは、独自の宣言、選択されたインポートされたクラス、およびインポートされたモジュールの組み合わせをエクスポートできます。

そのため、一方では、ドキュメントはユーザーが特定のモジュールを再エクスポートすることを思いとどまらせると同時に、そうすることで非常に便利になると述べています。

NgModuleの再エクスポートの概念は、制御が少ないことを除けば、ESモジュールの再エクスポートの概念と似ています。 JavaScriptは静的にスコープされており(そうです、 thisはそうではないことを私は知っています)、それはその最大の強みの1つであり、非常に柔軟な構成と情報の隠蔽を可能にします。 JavaScriptはシャドウイングもサポートしているため、スコープをオーバーライドする方法が常にあります。

ただし、最大の問題は、ガイドラインの例がすべて、@ angle / *フレームワークモジュールをインポートする方法を中心に展開していることです。 これらは、競合を直感的に防止できるように自然に分割できます。 これは、一般的に重複しないインフラストラクチャレベルのサービスを提供するために存在するためです。 ユーザー定義のモジュールは多くのレイヤーにまたがることができ、さまざまな動作を強化または変更したい場合があります。 たとえば、ロギングモジュールは、ルーターおよびHttpサービスへのアクセスを必要とすると同時に、管理ユーザーに情報を表示するためのいくつかのコンポーネントを提供し、フォームモジュールの1つを使用してそれらを定義する場合があります。

再エクスポートが推移的であるかどうかについては何も述べていないドキュメント...モジュールAはCommonModuleを再エクスポートします。 モジュールBはモジュールAを再エクスポートします。モジュールCはモジュールBをインポートします。つまり、モジュールCはCommonModuleからのディレクティブを使用できるようになりましたか?

@ Martin-Wegnerここで説明されているように推移的ですhttps://angular.io/docs/ts/latest/cookbook/ngmodule-faq.html#! #q-再エクスポート

@aluanhaddadどこ? 複数のホップを使用した推移的な再エクスポートについての単語が見つかりません...

@aluanhaddadがangularのドキュメントから取得したものを読むと、Angular 2について学んだことすべてを再考する必要があるように感じます。依存関係をより適切に処理するフレームワークがない場合でも、

私が理解しているように。 HttpModuleをインポートするアプリモジュールがあり、Httpサービスを使用するサービスを備えた機能モジュールがある場合、機能モジュールレベルではなくアプリモジュールレベルでHttpModuleをインポートする必要があります。 では、多くのアプリモジュール間で共有される機能モジュールを作成するとどうなりますか? AppModuleでインポートされたHttpModulebeeingを実際に使用する必要があります。 私の機能モジュールがHttpModuleに依存していることはわかりません。 これは本当に醜いことであり、NgModule定義にはPeerDependeciesなどの多くの機能が欠けていることを意味します。
ああ少年。 Angular2が壊れているように感じます。 最初からやり直して、Angular 2を放棄し、Angular3から始める時が来たのではないかと心配しています。

あなたが今言ったことには、実際には非常に多くの意味があります。 私はこれを始めました
昨年からangular2の旅で、殴打を感じる理由はありませんでした
これまでに見たすべての重大な変更にもかかわらず(アルファからベータへ、
およびRC)。 それはそれらの段階で理解可能であり、それは宗教的に立ち往生しているので
ミニマリストのBackbonejsから私を変換する際に使用した哲学に。
私にとってこのngModulesの全体的な考えは、いくぶん反論的であることが証明されました
生産的。 そして、私が福音宣教に費やしている間ずっと見るのは悲しいことです
ミニマリストで膨満感のない「コンポーネント」の豊かな良さは、
絶対に無駄です。
2016年8月29日午前9時44分、「DanielSchuba」 [email protected]は次のように書いています。

@aluanhaddadhttps ://github.com/aluanhaddadが取得したものを読む
角度のドキュメント私は私が持っているすべてを再考しなければならないような気がします
Angular 2について学び、おそらくそのフレームワークがなくても
より良い方法で依存関係を処理します。

私が理解しているように。 HttpModuleをインポートするアプリモジュールがあり、
Httpサービスを使用するサービスを備えた機能モジュールがあります。
機能モジュールレベルで、ただしアプリモジュールレベルでHttpModuleをインポートします。 だから何
多くのアプリモジュール間で共有される機能モジュールを作成した場合はどうなりますか? 私は持っている
AppModuleでインポートされたHttpModulebeeingを実際に使用します。 わからない、
私の機能モジュールはHttpModuleに依存しています。 それは本当に醜いです
つまり、NgModule定義には、たとえば次のような多くの機能が欠けています。
PeerDependecies。
ああ少年。 Angular2が壊れているように感じます。 私はそれがする時間だと恐れています
最初からやり直し、角度2を放棄し、角度3から始めます。


このスレッドにサブスクライブしているため、これを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/angular/angular/issues/10552#issuecomment -243066961
またはスレッドをミュートします
https://github.com/notifications/unsubscribe-auth/AF675h8_np9i5cHgL8mMOOu8vMMQmWKkks5qkpv8gaJpZM4Jee-o

私が間違っている場合、誰かが私を訂正できますか?

次のようにアプリを整理することを考えています。

アプリ
|-法律/
| ---- ManyComponents。
| ---- LawNGModule。
|-ユーザー/
| ---- ManyComponents
| ---- UserNGModule
| --AppNGModule
| --SomeFirstLeveComponents

AngularMaterialを使用したいとします。 以前は、すべてのコンポーネントの各要素をインポートするボイラープレートが多すぎるのが嫌いでした。 次に、NGモジュールに追加します。 ただし、機能ごとに1つのngモジュールを使用することにしたので、検討するngモジュールごとにインポートを実行する必要があります。 ルートだけではありません。 そうですか?

または、モジュールxを作成してy(Material)を別のモジュールに再エクスポートし、それを必要なモジュールにインポートする場合もありますか?

@ReneVallecilloその通りです。 各機能モジュールにインポートする必要があります。 または、他のモジュールと一緒に共有モジュールに追加し(依存関係を非表示にします)、それを再エクスポートして、この共有モジュールを使用します。 また、別のモジュールを再エクスポートすると、すぐにそれを認識して確認しなくても、インポートが重複する可能性があります。

@robwormald上記のコメントに応えて:

ただし、AoTモードでは、これは少し異なります。ビルド時に、デコレータをスキャンして、ソースコードから同じメタデータを静的に(つまり、コードを実行せずに)抽出します。

これは、元のソースコードからモジュールを静的に抽出していることを意味します。そのため、モジュールを動的に作成することは事実上できません。

移行を容易にするために、モジュールを動的に作成する関数を作成することを考えていました。 このようなもの:

function createModule (entryComponent: Type, dependencies: Type[]) {
    @NgModule({
        imports: [CommonModule, FormsModule],
        declarations: [entryComponent, ...dependencies],
        exports: [entyComponent]
    })
    class FeatureComponent {}
    return FeatureComponent;
}

したがって、これは(おそらく?)JITコンパイルでは機能しますが、AoTはソースコードを静的に解析してデコレータを探すため、AoTでは機能しませんか?

ES @ next .... @aluanhaddadの時代におけるこの不必要な複雑さは、いくつかの非常に良い点を示しています。

現状では、これが意図された方向である場合、Angular2で自分/チームが前進することはおそらくわかりません。 そして、これは「閉鎖」されているので、そうであるようです。

@DaSchTourのように、他のフロントエンドフレームワークを調査する必要があるかもしれません。 残念なことに、数か月前、NG2は一緒に仕事をするのがとても楽しかったし、私の明らかなゴミからの選択でした。

@iyoboは、切り替えの最初の苦痛を除けば、NgModulesに関するフィードバックの_vast_過半数(および私は開発者の_lot_と話します)は肯定的です。

hello worldアプリで単独で見ると、その「複雑」(上記の説明によれば、「不要」は実際には正しくありません)と主張することができますが、実際のアプリケーションでは、機能の整理、遅延ルーティング、 AoTはすべて、NgModuleを使用して非常に簡単になります。 今日の選択を考えると、私はまだフレームワークにNgModulesを追加することを選びます。

私はここで@robwormaldと一緒にいますが、RC4 / 5からNgModulesに移行する最初の苦痛は、新しく作成されたページにすべてのコンポーネント/パイプをインポートする必要がないという利点を確認した後、管理できました。
NgModuleは、もう少し複雑になり、多くの共有コンポーネントを使用した後、輝き始めます。

SharedModuleをインポートして、それで実行するのはとても簡単です。

ねえ@ robwormald 、Ng2の現在の方向性に同意しないという考えは、「HelloWorld」レベルのアプリでのみ機能するという事実上の主張ではありません。

あなたが話すこの「機能のコンパートメント化」は新しいものではありません。 これは、コンポーネントを使用する個々の製品/ソリューションに合わせて、必要に応じて常に設計されてきたものです。
とは言うものの、それ自体が何を必要としているかを宣言するコンポーネントほど、実際には大きな区分化はありません。

遅延読み込み、引き戻し、鳥瞰的な視点から物事を見る場合、遅延読み込みの主な利点は、アプリの読み込み速度を向上させることです。 私たちの大多数は、これを機能させるパイプラインを持っていると思います。 Webpackで縮小、圧縮、複数のアプリエントリポイントを入力します。

NgModulesは、実際の問題の解決策ではなく、問題を探すための解決策であるように私には思えます。 しかし、繰り返しになりますが、私はすべてを知っているとは言えません...

NgModulesを導入することが良い考えであったかどうかは、時が経てばわかると思います。 Angular 2は現在、特定の設計目標を達成するためだけに作られているという印象を持っています。 スキルレベルの異なるチーム、古くなり、何世代にもわたる開発者に受け継がれているコードなどについては、誰も考えていません。 理想的な世界では、それは素晴らしいアイデアのように見えるかもしれません。 しかし実際には、NgModulesは多くのトラップと難読化を導入し、トレーニングと新しいプロジェクトへの導入の段階で多くの問題を引き起こします。 コンポーネントレベルでの宣言の場合ほど単純で直感的ではありません。 依存関係はモジュールに隠されており、コンポーネントが含まれているモジュールの調査を開始するのは時間の問題です。

最近、より大きなアプリケーションをNgModulesに移行したので、それらはほとんど良いことだと思います(これで完了したので、それは確かに理にかなっています)。 実際のところ、大きな問題は、異なるコンポーネント構造が必要なことだと思います。これは、以前のアプリケーションの構造にうまく適合しなかった可能性があります(少なくとも私の場合はそうでした)。

しかし、私はそれらが唯一の解決策として存在するべきではないと感じています。 コンポーネントが非常に一般的にどのように構築されているかを見ると、非常に多くの場合、それらはより小さな高度に専門化されたサブコンポーネントで構成されていることがわかります。 そのコンテナコンポーネントの外部に目的がないこれらのサブコンポーネントの場合、より高いスコープのモジュールでそれらを維持する必要があることは本当に退屈であり、スコープの問題にすぐに屈する可能性があります。

NgModulesに、コンポーネントが他のコンポーネントまたはディレクティブを、その正確なコンポーネント内でのみ適用されるローカルスコープの依存関係として定義できるメカニズムがあれば本当にありがたいです(モジュールの前にdirectivesリストが機能したように)。

フルNgModuleを使いたくない人のために代替案を用意するという@pokeの提案が好きです。

NgModulesは、コンパイルと遅延読み込みを機能させる際の問題を解決するためにRC5に追加されました。これは、元のマスタープランの一部ではないため、一部のユースケース(特に、オリジナルの「コンポーネントは王様」のデザイン)。

もちろん、それらはいくつかのことを修正または有効にしますが、独自の複雑さももたらします-人々が学び、設計するためのより多くのことは、すべてのベストプラクティスとアプローチがまだ解決されていない場合に特に困難です。 早期採用は多くの苦痛をもたらす可能性があります、私はRC4への乗車からそれを学びました。

私は元のコンポーネント中心の計画がもっと好きでした。それがおそらく、Polymer / WebComponentsが今より適していると思っている理由です。 モジュールは、Angular1に戻った半音のように感じます。

最初は、パイプとディレクティブを削除するというこの変更には抵抗しましたが、今ではそれに慣れており、最初に思ったほど悪くはないようです。

複数のコンポーネントが複数のレベルで複数の他のコンポーネントを必要とする非常に複雑なアプリでNgModulesがどのように機能するかを誰かに教えてもらえますか? 私が見たすべてのチュートリアル、例、およびリポジトリは、モジュールがそれ自体のものをカプセル化し、それらの一部を他の人に公開(エクスポート)する簡単な方法を示しているだけです。

実際のプロジェクトでは、通常は階層チェーンを持つ、相互に必要な依存関係が多数あります。 そのために正確に指定された例によって何かの概念を証明することは、どういうわけか間違っています。

@ Angular2のすべての作者のために:NgModulesのネガティブな部分を正直に教えてください。 私はあなたがすべての良いことについて本を書くことができることを知っています。 大丈夫だよ。 しかし、私は常に、あなたがそれらについて話さなければ明らかにならないであろう隠された悪いことに対処する必要があります。

複数のコンポーネントが複数のレベルで複数の他のコンポーネントを必要とする非常に複雑なアプリでNgModulesがどのように機能するかを誰かに教えてもらえますか?

これを行う1つの方法は、これらのコンポーネント専用の依存関係モジュールを作成することです。複数のコンポーネントを含む3セットのコンポーネントAB 、およびCがあるとします。それぞれのセットには、いくらか関連しているものがあります。 したがって、これらの3つのセットは、3つの別々のモジュールでうまく機能します。

現在、これらの各セットのコンポーネントには、セットDの複数のコンポーネントが必要です。 Dのこれらのコンポーネントは、これら3つのセットのコンポーネントにのみ使用されます。 それらはすべてで使用されているため、コンポーネントをそれらのモジュールに追加することはできません(コンポーネントは単一のモジュールの一部である可能性があるため)。 この時点で、 ABC 、およびDを巨大なモジュールにマージできるため、すべての依存関係が存在します。 しかし、それはもちろん非常に厄介です。 代わりに、これらの依存関係のみを含むDの新しいモジュールを作成するだけです。 このモジュールは、それらのモジュールへのアクセスを提供する以外に何もしません。 これで、そのモジュールを他の3つのモジュールのそれぞれにインポートして、コンポーネントを使用できるようになります。 ただし、コンポーネントはまだ「プライベート」であるため、モジュールを再エクスポートしたり、モジュールDを他のモジュールにインポートしたりすることはありません。

モジュールのインポートはモジュール自体にのみ影響するため、これにより、他のモジュールを汚染することなく、ある種のスコープが可能になります。 もちろん、より多くのモジュールを作成する必要がありますが、それがまさにその仕組みです。

現在の設定を共有できます。 アプリでCommonModule、AppModule、TestModuleの3つのモジュールを使用しました。

  • CommonModuleは、HttpModule、FormsModule、MdInputModuleなどの最も一般的なものをインポートおよびエクスポートします
  • AppModuleは、BrowserModule、CommonModule、app.routing、および個々のコンポーネントをインポートします
  • TestModuleはBaseModuleをインポートおよびエクスポートしますが、XHRBackendやMockBackendなどの一部のプロバイダーを上書きします

TestBed.configureTestingModuleを簡素化するために、このセットアップを導入しました。
そのため、TestModuleをインポートしてから、次のような単一のコンポーネントをインポートする必要があります。

TestBed.configureTestingModule({
  imports: [ TestModule ],
  declarations: [ MyFormComponent ]
});

RC-4からリリースに移行したときに明らかになったもう1つの欠点は、NgModulesが、コンポーネントを単純に分割する必要がある単純なリファクタリングに大きなペナルティを課すことでした。 NgModulesを使用する場合は、含まれているモジュールを変更する必要があります。これは、概念コンポーネントツリーの数レベル上にある場合があります。または、コンポーネントをNgModuleでラップしてから、親NgModuleから削除してコンポーネントをプロモートします。 コンポーネントのリファクタリングは不可欠です。

これは@pokeのポイントに直接関係しています

NgModulesに加えて、コンポーネントが他のコンポーネントまたはディレクティブを、その正確なコンポーネント内でのみ適用されるローカルスコープの依存関係として定義できるメカニズムがあれば本当にありがたいです(ディレクティブリストがモジュールの前にどのように機能したかと同じように)。

私は強く反対します。 Angular 2で提案されているモジュラーアーキテクチャは、必要に応じてスケーリング、調整、リファクタリングが簡単です。 確かに、RC4からRC5までは少し調整がありましたが、どちらかといえば、NgModulesははるかに柔軟なアプリケーションを可能にすることが証明されています。

Angularは意見が分かれており、1つのサイズですべてに対応できるわけではありませんが、NgModulesは、スマートでモダンで高性能なアプリケーションを設計する際の失敗点ではありません。

@ emilio-martinez:私の意見では、Angular 2がJiTを使用しているときにブートストラップがそれほど遅くなければ、NgModuleは導入されませんでした。 この議論が示すように、「スケーリング、調整、リファクタリング」のような他のすべての「改善」は議論の余地があります。

かなり久しぶりで、私たちの多くはNgModuleを仕事に完全に吸収する時間がありました。 かなりの数の人が説明しているように、新しいモジュールシステムに移行するスピードバンプを過ぎると、かなり素晴らしいことが可能になることは明らかだと思います。 NgModuleを吸収するのに問題があるこのスレッドに乗る人は、ずっとスクロールして、特に@robwormald@wardbellからすべてを読むことをお勧めします。

多くのAngular2 +アプリケーションが、モジュール、遅延読み込み、およびAOTを広範かつシームレスに使用するようになるのは、今から1年後のことだと思います。 ほとんどまたはほぼすべてのアプリケーションがこれらを使用して「プログレッシブアプリケーション」ビジョンを実装することは完全に日常的なことだと思います。大規模で複雑なアプリケーションでも、初期ロード時間がほぼ瞬時になり、機能を遅延ロード(または楽観的に遅延プリロード)します。必要。 結果は実際には非常に滑らかで、個々のアプリケーション開発者にとって非常に低コストで達成されます。NgModuleは基本的にそのコストであり、苛立たしい移行ですが、使用する継続的な作業はごくわずかです。

@kylecordesあなたが正しいことを願っています。それが正しい態度だと思います。

@ iurii-kyrylenkoそれは非常に真実です。

TypeScriptがJavaScriptをコンパイルすることになっているので、JavaScriptの角度コンパイルに問題がありますが、それは別の問題です。

@kylecordes移行だけでなく、考慮すべきことがたくさんあると思います。 モジュールは、独自のアプリケーションにバグを追加するために、多くの複雑さと多くの追加の可能性をもたらします。 最大の問題は、依存関係の難読化です。 これは、Angular2で開発する次の年に多くの問題を引き起こすでしょう。

@aluanhaddadAngularはtscラッパーを使用してコンパイルすると思います。 たとえば、タスクランナーワークフローに実装することもできるので便利です。

@ iurii-kyrylenkoのブートストラップ速度もRC4に基づいて決定するのは困難です。 それから最終リリースまでに行われた作業の多くは、クリーンアップと最適化です。 私の経験では、AngularでコンパイルされたJITは、とにかくRC4よりも高速に実行されます。

@DaSchTourは、NgModuleの操作中に見つけたバグについて詳しく説明できますか?

@ emilio-martinezこれは、NgModuleのバグではなく、インポートの欠落や、開発の初期段階で省略または検出されたサービスインスタンスの重複が原因で発生するバグです。 それは私がそれらを使用する場所に物を輸入することであり、それが必要であるか使用されているか、そしてそれが必要で使用されている場所であるかどうかわからない場所ではありません。

TypeScriptがこのように機能することを考えてみてください。 モジュールのベースファイルがあります。これを_index.ts_と呼びましょう。次のようになります。

import {foo} from bar;
import {StartComp} from start;

StartComp.boot();

このようなstart.tsというファイルがあります。

export class StartComp {
   public static boot() {
      foo()
   }
}

それがAngularがNgModulesで行っていることです。 魔法を使って何かをモジュールにインポートすると、アプリケーションのもう一方の端に表示されます。 fooがindex.tsにインポートされ、インデックスからStartCompを実行することにより、そのインポートをコンポーネントで使用できることを知っておく必要があります。

依存関係は隠されており、それらを見つけるには追加の調査が必要です。

@ emilio-martinez

私の経験では、AngularでコンパイルされたJITは、とにかくRC4よりも高速に実行されます。

MEANスタックとAngular2ファイナルに基づいた中程度の複雑さのプロジェクトがあります。 AndroidデバイスでJITモードのブートストラップを完了するには約10秒かかります。 これはかなりの遅れだと思います。 現在、ソースコードを変更せずにAOTコンパイルを使用することはできません(プライベートメンバー、エルビス演算子の問題...)。

実際のプロジェクトのパフォーマンスAOT +遅延読み込みに関する情報はありますか?

Angularはtscラッパーを使用してコンパイルしていると思います。 たとえば、タスクランナーワークフローに実装することもできるので便利です。

@ emilio-martinezこれはまさに私が望まないものです。 TypeScriptのバージョンを使用してコードをコンパイルしたいのですが、たとえば、async / awaitに対してダウンレベルのemitがある2.1.0-devなどです。 TypeScriptファイルのコンパイルをAngularに任せたくありません。これはフレームワークに委任するべきではなく、言語の役割です。 トピックからさらに離れることなく、私は10フィートのポールで@Scriptに触れなかったでしょう、それが死んでいることを感謝します。
ワークフローに関しては、従来のタスクランナーではなく、JSPMと、場合によってはWebpackを使用し、IDEにリンターを処理させます。

もう1つの問題は、角度のあるデコレータを抽象化するデコレータを作成したことです。今では、aotがそれらを無視することを理解しています。 デコレータの角度がどれほど重いかを考えると、フレームワークがデコレータを完全にサポートしておらず、AOT中に、実際には基礎となる言語のランタイム構造である場合に静的アノテーションとして扱うことを知り、非常に失望しました。

@aluanhaddad AoTコンパイル中に発生する2つの異なるステップがあることを理解することが重要です。1つは_new_タイプスクリプトコードの生成であり、2つ目はそのコードをES5 / 6にトランスパイルすることです。 ngcは両方とも便利ですが、AoTに固有のものでそれを必要とするものはありません。 グーグルの内部では、両方を行うので、その場合が優先されます。 誰でもコンパイラホストを実装して、必要な環境でコード生成をサポートできます。

Angularに組み込まれているデコレータの上での抽象化は(まだ)サポートされていませんが、 https://www.npmjs.com/package/core-decoratorsのようなものを使用したい場合は、それで問題ありません。

@ iurii-kyrylenkoは、LucidChartsがAoTでの経験について語ったAngularConnectの初日の基調講演をご覧になることをお勧めします。 https://youtu.be/xQdV7q3e_2w?t=1411を参照してください

IMHO-みんなの一番の目標は、できるだけ早くAoTコンパイルに取り掛かることです。 パフォーマンスは単に無敵です。

@robwormald ngcを呼び出すときに使用できるオプションを確認していません。したがって、これについてはすでに説明している可能性があります。 これらのオプションは、NGCが利便性/最適化として第2の目的に存在する主な理由として第1の目的を果たしていることを明らかにすれば、ここで述べたような懸念を和らげることができると思います。 ドキュメントまたはヘルプに、既製のtscを個別に実行する方法が示されている場合は、懸念をさらに緩和できますか?

@kylecordes私は、ドキュメントがあなた自身のコンパイラホストを実装する方法をすぐにカバーするつもりはないと思います。 その高度なユースケースであるため、実装するには自主的な学習が必要になります。 ここでCLIに同様のことを実装しましたhttps://github.com/angular/angular-cli/tree/master/packages/webpack

@robwormaldああ、私はあなた自身のコンパイラホストを実装することを意味しません。 私は2行の「ビルドプロセス」を意味しました-最初にngcを呼び出して生成されたタイプスクリプトを出力し、次にtscを呼び出してすべてのタイプスクリプト(ソースと生成されたソース)をコンパイルしますJavaScript。 これにより、タイプスクリプトコードが既成のタイプスクリプトコンパイラによってJSにコンパイルされているだけであることがすぐにわかります。

@robwormaldお返事ありがとうございます。
NGCに関して、私が知りたいのは、TypeScriptコンパイラのバージョンと設定をTS -> TSパスで制御できるかどうかです。 TypeScriptをNGCに渡すことはできますか、それとも特定のTypeScriptバージョンをラップする特定のバージョンを使用する必要がありますか? それらはどの程度結合されていますか?

デコレータに関して、Angularデコレータを抽象化するユーザー定義のデコレータの問題追跡サポートはありますか? https://www.npmjs.com/package/core-decoratorsはデコレータの直交セットですが、AngularデコレータをラップすることでAngularアプリにパターンと規則を適用するデコレータがあります。 これの明らかな使用例は、パッケージ全体のコンポーネント名プレフィックスを自動的に作成して適用することですが、他にもあります。

NGCはこれをサポートしていないので、どのデコレータがAngular固有であるかをどのようにして知るのでしょうか?
名前で角度のあるデコレータと一致しますか?
JavaScriptの字句スコープに違反するからではないことを願っています。
簡単なシナリオ
_awesome-component-decorators.ts_

import { Component } from '@angular/core';
import template from './awesome-component.html';
import style from './awesome-component.less';

export const awesomeComponet = <T extends new (...args) => any>(target: T) =>
  Component({template, styles: [style], selector: snakeCase(target.name) })(target);

_consumer.ts_

import { awesomeComponet } 'app/shared/awesome-component-decorators';

<strong i="19">@awesomeComponent</strong> 
export class AnAwesomeComponent { }

<strong i="20">@awesomeComponent</strong> 
export class AnotherAwesomeComponent { }

@jpsfsルートアプリケーションモジュールにコンポーネント宣言を追加せずにコンポーネントを動的にロードするソリューションを見つけましたか? 。

私はAngular1.XからAngular4への移行プロジェクトにも参加しています。 このプロジェクトには、アプリケーションコンテキストに基づいて遅延ロードされる、さまざまなアプリケーションで再利用される多数のコンポーネントがあります。

Angular4での私の理解によると

以下のように、ルート@NgModule宣言にコンポーネントの依存関係を追加する必要があります。

「@angular / platform-b​​rowser-dynamic」から{platformBrowserDynamic}をインポートします。
import {Component、NgModule} from "@ angle / core";
..。
..。
@NgModule({
imports:[BrowserModule]、// AngularのBrowserModuleをインポートします
bootstrap:[BootStrapComp]、//ブートストラップコンポーネントを示します
宣言:[com1、comp2、comp5 ...... Comp n] //コンポーネントをモジュールに登録します
})
エクスポートクラスAppModule {}

platformBrowserDynamic()。bootstrapModule(AppModule);

しかし、私たちの場合、コンパイル時のコンポーネントの依存関係を知るためにNgModuleをルート化する必要はありません。 むしろ、実行時にコンポーネントを動的にロードする必要がありました。
すべてのコンポーネントをルートNgModule宣言に追加せずにアプリケーションをブートストラップできる優れたソリューションを見つけましたか(コンポーネントごとに1つのNgModuleも必要ありません:))

@DaSchTour

アプリのエントリポイントがこのようになっていたことを覚えていますか?

そのために、ビルドスクリプトを使用して、これらのモジュールを自動的に要求し、アプリモジュールに追加する人もいました。

私はangular2で似たような簡単な解決策を探しています。

@samudrak Angular aotサポートを使用する場合は、コンポーネントだけを遅延ロードすることはできません。 コンポーネントごとに遅延モジュールを設定し、モジュールを遅延ロードする必要があります。 アプリケーションでも同様のアプローチを使用しています...

ECMAScriptと現在のTypeScript(読み込みに直交する完全な型チェックを使用)で動的インポートがサポートされているため、遅延読み込みのユースケースはかなり恣意的です。 もちろん、後知恵は20/20であり、それが起こることを知る方法はありませんでした。

この問題は、非アクティブのために自動的にロックされています。
同様の問題または関連する問題が発生した場合は、新しい問題を提出してください。

自動会話ロックポリシーの詳細をご覧ください。

_このアクションはボットによって自動的に実行されました。_

このページは役に立ちましたか?
0 / 5 - 0 評価