1. ホーム
  2. angular

Angular2: CoreModuleとSharedModuleの比較

2023-08-26 01:08:56

質問

誰か SharedModuleCoreModule を意味するのでしょうか?

私は、いくつかのプロジェクトがangularプロジェクトを構築するために、このアプローチを使っているのを見てきました。

  1. なぜ2つのモジュールが必要なのですか?
  2. いつ、それぞれをインポートすればよいのですか?
  3. どの imports , exports , declarations はそれぞれ持つべきでしょうか?

どのように解決するのですか?

TLDR。

  1. CoreModule のみであるべきです。 services で一度だけインポートされ AppModule .
  2. SharedModule 以外のものがあるはずです。 services であるべきで、共有されたものを必要とするすべてのモジュールでインポートされなければならない。 AppModule ).

しかし

現実のモジュールは、しばしば[上記の]ガイドラインから意図的に逸脱したハイブリッドです。これらのガイドラインは法律ではありません。そうしなければならない正当な理由がない限り、従ってください。


RTFM :

ということで、一通り NgModules' ドキュメント を調べると (さらに文脈を理解するために他のものも)、簡単に あなたの2番目と3番目の質問に対する答え そこで . ここにあります。

共有モジュール

  • を作成します。 SharedModulecomponents , directives そして pipes といった、アプリ内のあらゆる場所で使用するものです。このモジュールは、すべて declarations で構成されるべきで、それらのほとんどはエクスポートされます。
  • SharedModule のような他のウィジェットモジュールを再エクスポートすることができます。 CommonModule , FormsModule と、最も広く使用する UI コントロールを含むモジュールです。
  • SharedModule を持つべきではありません。 providers を持つべきではありません。また、インポートまたは再エクスポートされたモジュールもプロバイダを持ってはいけません。このガイドラインから外れる場合、何をしているのか、なぜなのかを知っておいてください。
  • をインポートします。 SharedModule をインポートしてください。

コアモジュール

<ブロッククオート
  • を作成します。 CoreModuleproviders で、アプリケーションの起動時にロードするシングルトンサービスを指定します。
  • インポート CoreModule をルートで AppModule だけで済みます。決して CoreModule を他のモジュールでインポートしてはいけません。
  • を作ることを検討する。 CoreModule のない純粋なサービスモジュールにすることを検討します。 declarations .

よりも詳細ですが、これらは TLDR バージョンよりも詳細で、コーディングを続けることができますが、理解するためにドキュメントを読まなければならないことがいくつか書かれています (例えば 'widget module", "reasons explained previously", "pure service modules") そして、それはまた はあなたの最初の質問に答えていません。 .

では、そうしてみましょう!


なぜ2つのモジュールが必要なのですか?

あなたは は必要ありません。 の2つのモジュールが必要です。これはdocsにあるものです。

ルートモジュールは、いくつかのコンポーネントを持つ単純なアプリケーションで必要なものです。

そうは言っても、まず違う質問をすることが重要です。

なぜ人々はプロジェクトを複数のモジュールに編成するのでしょうか。

これに関する基本的な説明は、docsの上記の文のすぐ後にあります。

アプリが成長するにつれて、ルート モジュールをリファクタリングして、関連する機能のコレクションを表す機能モジュールにします。そして、これらのモジュールをルート モジュールにインポートします。

しかし、「なぜ」と聞かれましたが、これには基本的な説明以上のものが必要です。そこで、いくつかの 問題点 が発生する可能性があります。 を分離しない 機能モジュールに分離しない場合です。

  • ルートモジュールは、すべての依存関係 (サードパーティのモジュールなど) をインポートし、すべてのサービスを提供し、すべてのコンポーネント、ディレクティブ、パイプを宣言しなければならないため、コードが乱雑になり始め、読みにくく作業しにくいものになります。アプリが必要とするものが多ければ多いほど、このモジュールは大きくなります。
  • 異なる機能の間に明確な境界がないため、アプリの構造を理解するだけでなく、チーム内で異なる責任を持つことが難しくなっています。
  • アプリの異なる部分間の競合を解決しなければならなくなる可能性があります。たとえば、アプリの 2 つの異なる部分で同じことを行うディレクティブまたはコンポーネントがある場合、それらを区別するために長い名前を使用し始めるか、インポート時に名前を変更する必要があります。

上記の例は必ずしも問題ではないと思うかもしれませんが (もしかしたらあなたは一人で仕事をしていて、自分の混乱に耐えられるかもしれませんし、チームメイトもみんな混乱しているかもしれません)、他の人は確実にあなたに同意しないことを心に留めておき、そのために "has been watching several project[s] out there ... using this approach" .

あなたがそれに同意し、成長するアプリを機能モジュールに整理したいことを考慮すると、docsからの次の記述に注意してください。

ルートモジュールとフィーチャーモジュールは、同じ実行コンテキストを共有します。これらは同じ依存性インジェクターを共有します。つまり、1 つのモジュール内のサービスはすべてで利用できます。

モジュールには以下のような重要な技術的差異があります。

  • アプリを起動するために root モジュールを起動し、アプリを拡張するために feature モジュールをインポートします。
  • 機能モジュールは、他のモジュールからその実装を公開したり隠したりすることができます。

決して忘れてはならない情報。 一方、コンポーネント、ディレクティブ、パイプのような他のものは、それらを使用したい各モジュールに注入する必要があります。

この情報をもとに、次の質問に答えることで、知りたいことに近づいていくことができます。

すべての機能モジュールは同じですか?

NO! 少なくとも、ルートモジュールだけではいけないと示唆されているように、両者はイコールではないのですが、やりたいことは何でもできるのです。しかし、そうすべきではないのです。

docs には、提案された機能モジュール群の違いを示す表があります。その抜粋を見てみましょう。

FEATURE   SHOULD HAVE    SHOULD HAVE   SHOULD HAVE
MODULE    DECLARATIONS   PROVIDERS     EXPORTS         

Domain    Yes            Rare          Top component   
Routed    Yes            Rare          No              
Routing   No             Yes (Guards)  RouterModule    
Service   No             Yes           No              
Widget    Yes            Rare          Yes             

ATTENTION! 彼らは、これはかなり明確にする...

...いくつかのアプリケーションで NgModule を使用した初期の経験に基づく予備的なガイダンスです。 NgModule をいくつかのアプリケーションで使用した初期の経験に基づく予備的なガイダンスです。

繰り返しますが、このガイドラインに固執する必要はありませんし、逸脱も起こり得ますが、自分が何をしているのか、なぜそうするのかを知っておくべきです。

では、この表を分析してみましょう。

  • ServiceWidget のグループだけが、それぞれの列で完全に異なる値を持っています。
  • DomainRouted グループは、基本的に Widget グループと基本的に同じですが、エクスポートが制限されているか、全く行われていないだけです。
  • Routing グループは基本的に Service グループで、エクスポートの例外があり、特定のプロバイダに限定されています。

では、次に Domain , RoutedRouting の変種に過ぎません。 Service または Widget で、この最後の2つに注目してください。

サービス は、あなたの注意を喚起する必要があります。あるモジュールのサービスがすべての[モジュール]"で利用可能であることを決して忘れてはならないことを覚えてる?さて、彼らが機能モジュールグループを呼び出す場合 Services と呼ばれる場合、それは他のモジュールから分離されている必要があるため、一度だけインポートすることができます。例として UserModule のようなサービスから構成される SignUpService , SignInService , SocialAuthServiceUserProfileService . どこにインポートしても、その UserModule をインポートすると、そのすべてのサービスがアプリ全体で利用できるようになります。そして、上の表のように、宣言やエクスポートを持たず、プロバイダーだけを持っている必要があります。

ウィジェット はより一般的なものに聞こえますが、これは何かを教えてくれるはずです。また、次のことも忘れてはいけません。 "コンポーネント、ディレクティブ、パイプなどの他のものは、それらを使用したい各モジュールに注入する必要があります"。 ? ということで、これらに使用するモジュールの種類です。例えば UIModuleButtonComponent , NavComponent , SlideshowComponent , HighlightLinkDirective , CtaPipe . そして、エクスポートされた要素の1つまたはすべてを使用する必要がある場合は、そのたびに UIModule .

つまり、基本的にAngularのサービスの扱い方によって、機能を機能モジュールに分割し始めると、サービスを独自のモジュールに分離する必要があります。

どのように CoreModuleSharedModule は、この中に入るのでしょうか?

簡単に説明すると CoreModuleService モジュールと SharedModuleWidget モジュールに含まれています。で一度だけインポートする必要があるのはそのためです。 AppModule で一度だけインポートし、後者はそれを必要とするすべてのモジュールでインポートすべきなのです。上の私の例からすると UserModule がインポートされ CoreModuleUIModule によって SharedModule .

しかし、先に述べたように、これらはガイドラインであり、逸脱は起こり得ます。彼ら自身の例でも、コンポーネントを CoreModule でコンポーネントを宣言していますが、観察を加えています。

このページのサンプルでは、このアドバイスから離れ、[li]メソッドで宣言し、エクスポートしています。 CoreModule で] 宣言し、エクスポートしています。このコンポーネントは、AppModule によって宣言されたルート AppComponent の中でのみ使用されます。このガイドラインに厳密に従う人は、これらのコンポーネントを代わりにAppModuleで宣言したことでしょう。


個人的には、最大の混乱は命名の選択に関するものだと思います。一般に、アプリのコア部分 (ユーザーのもの、NavBar、ロード バー、トースターなど) は、すべて CoreModule に入れ、複数の機能で共有するものはすべて SharedModule .

すべてのサービスはすべてのモジュールで共有され、どのサービスも SharedModule と同様に NavbarComponent はアプリのコアの一部であり、どのコンポーネントも CoreModule .

いずれにせよ、そうしない理由が見つかるまで、ガイドラインに従うことをお勧めします。

そして、ガイドラインをよりよく理解するために、上の表の残りを紹介します。

FEATURE   CAN BE                 SOME
MODULE    IMPORTED BY            EXAMPLES

Domain    Feature, AppModule     ContactModule (before routing)
Routed    Nobody                 ContactModule, DashboardModule,
Routing   Feature (for routing)  AppRoutingModule, ContactRoutingModule
Service   AppModule              HttpModule, CoreModule
Widget    Feature                CommonModule, SharedModule

乾杯