Angular2でモジュール設計をマスター:CoreModuleとSharedModuleを使いこなすためのチュートリアル
Angular2におけるCoreModuleとSharedModuleは、モジュール設計において重要な役割を果たす概念です。それぞれ異なる目的を持ち、適切な使い分けがアプリケーションの構造性と保守性を高めます。本記事では、CoreModuleとSharedModuleの詳細な違いを解説し、それぞれの役割と使い分けについて分かりやすく説明します。
CoreModuleは、アプリケーション全体で共有されるサービスを登録するモジュールです。主に以下の役割を担います。
- シングルトンサービスの提供: アプリケーション全体で唯一のインスタンスとして使用されるサービスを登録します。例えば、認証サービスやロギングサービスなどが該当します。
- 依存関係の定義: アプリケーション全体で必要な依存関係を定義します。これにより、各コンポーネントやサービスが必要なリソースを容易に取得できます。
- ブートストラップ処理: アプリケーション起動時に実行されるブートストラップ処理を定義します。ルーティングやインターセプターの設定などが含まれます。
CoreModuleは通常、アプリケーションのルートモジュールであるAppModuleにのみインポートされます。これは、CoreModule内のサービスがアプリケーション全体で共有されるためです。
SharedModule:共通コンポーネントとディレクティブの共有
- 共通コンポーネントの提供: ボタン、ヘッダー、フッターなどの共通コンポーネントを登録します。これらのコンポーネントは、アプリケーション内の様々なモジュールで再利用できます。
- 共通ディレクティブの提供: 日付書式化、入力検証などの共通ディレクティブを登録します。これらのディレクティブは、コンポーネントのテンプレートで再利用できます。
- スタイルの共有: アプリケーション全体で共通するスタイルを定義します。これにより、アプリケーション全体のデザインの一貫性を保ちやすくなります。
SharedModuleは、共通コンポーネントやディレクティブを必要とするすべてのモジュールにインポートされます。複数回のインポートでも問題ありません。
CoreModuleとSharedModuleは、以下の点で使い分けられます。
項目 | CoreModule | SharedModule |
---|---|---|
目的 | サービスの登録 | コンポーネントとディレクティブの共有 |
対象 | アプリケーション全体 | 共通コンポーネント/ディレクティブを使用するモジュール |
インポート | AppModuleのみ | 共通コンポーネント/ディレクティブを使用するモジュールすべて |
内容 | シングルトンサービス、依存関係、ブートストラップ処理 | ボタン、ヘッダー、フッター、共通ディレクティブ、スタイル |
CoreModuleとSharedModuleは、Angular2におけるモジュール設計において重要な役割を果たす概念です。それぞれの役割と使い分けを理解することで、アプリケーションの構造性と保守性を高めることができます。
補足
- CoreModuleとSharedModuleは、必ずしも必要ではありません。アプリケーションの規模や複雑性に応じて、適切なモジュール設計を選択してください。
- 近年では、Angular CLIなどのツールを使用することで、CoreModuleとSharedModuleの自動生成が可能になっています。
Angular2におけるCoreModuleとSharedModule:サンプルコード
CoreModule
import { NgModule } from '@angular/core';
import { AuthService } from './auth.service';
import { LoggingService } from './logging.service';
@NgModule({
providers: [
AuthService,
LoggingService
]
})
export class CoreModule {}
import { NgModule } from '@angular/core';
import { CommonButtonComponent } from './common-button.component';
import { DateFormatterDirective } from './date-formatter.directive';
@NgModule({
declarations: [
CommonButtonComponent,
DateFormatterDirective
],
exports: [
CommonButtonComponent,
DateFormatterDirective
]
})
export class SharedModule {}
AppModule
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { FeatureModule } from './feature.module';
import { CoreModule } from './core.module';
import { SharedModule } from './shared.module';
@NgModule({
imports: [
BrowserModule,
FeatureModule,
CoreModule,
SharedModule
],
declarations: [
AppComponent
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {}
解説
上記のサンプルコードでは、以下のモジュールを定義しています。
- CoreModule: AuthServiceとLoggingServiceという2つのサービスを登録します。これらのサービスは、アプリケーション全体で共有されます。
- SharedModule: CommonButtonComponentとDateFormatterDirectiveという2つのコンポーネントとディレクティブを登録します。これらのコンポーネントとディレクティブは、アプリケーション内の様々なモジュールで再利用できます。
- AppModule: CoreModuleとSharedModuleをインポートし、AppComponentをルートコンポーネントとして設定します。
このサンプルコードはあくまでも一例であり、アプリケーションの規模や複雑性に応じて、モジュールの構成は変更する必要があります。
- サービスは、
providers
プロパティで登録します。 - コンポーネントとディレクティブは、
declarations
プロパティで登録します。 - 登録したコンポーネントとディレクティブを他のモジュールで使用する場合は、
exports
プロパティでエクスポートする必要があります。 - モジュールをインポートする場合は、
imports
プロパティを使用します。
Angular2におけるCoreModuleとSharedModule以外にも、モジュール設計を整理する方法として、以下の選択肢があります。
Feature Modulesは、特定の機能に特化したモジュールです。各Feature Moduleは、その機能に必要なコンポーネント、サービス、ディレクティブなどを登録します。Feature Modulesは、アプリケーションを機能ごとに分割することで、モジュールの責任範囲を明確にし、保守性を高めることができます。
例:
// user.module.ts
import { NgModule } from '@angular/core';
import { UserListComponent } from './user-list.component';
import { UserDetailComponent } from './user-detail.component';
import { UserService } from './user.service';
@NgModule({
declarations: [
UserListComponent,
UserDetailComponent
],
exports: [
UserListComponent,
UserDetailComponent
],
imports: [
SharedModule
],
providers: [
UserService
]
})
export class UserModule {}
Lazy Loadingは、必要なモジュールを遅延読み込みする機能です。これにより、アプリケーションの起動時間を短縮し、パフォーマンスを向上させることができます。
// app-routing.module.ts
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { UserModule } from './user.module';
const routes: Routes = [
{ path: 'users', loadChildren: () => import('./user.module').then(m => m.UserModule) }
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule {}
NgRxは、状態管理ライブラリです。NgRxを使用すると、アプリケーションの状態を中央集権的に管理することができます。これにより、モジュール間のデータ共有を容易にし、コードをよりシンプルにすることができます。
// app.component.ts
import { Component } from '@angular/core';
import { Store } from '@ngrx/store';
import { AppState } from './app.state';
@Component({
selector: 'app-root',
template: `
<user-list [users]="users"></user-list>
`
})
export class AppComponent {
users: User[];
constructor(private store: Store<AppState>) {
this.store.select('users').subscribe(users => this.users = users);
}
}
Barrel Filesは、関連するモジュールを1つのファイルにまとめる手法です。これにより、モジュールのインポートとエクスポートを簡略化することができます。
// shared/components/index.ts
export * from './common-button.component';
export * from './date-formatter.directive';
Monorepoは、複数のプロジェクトを1つのリポジトリで管理する手法です。これにより、プロジェクト間の依存関係を管理しやすくなり、開発効率を向上させることができます。
my-app/
├── apps/
│ ├── core
│ │ ├── core.module.ts
│ │ └── logging.service.ts
│ └── shared
│ ├── common-button.component.ts
│ └── date-formatter.directive.ts
├── packages/
│ └── auth
│ ├── auth.service.ts
│ └── auth.module.ts
└── nx.json
Angular2におけるモジュール設計は、アプリケーションの規模や複雑性に応じて、様々な方法があります。上記の選択肢を参考に、アプリケーションに最適な方法を選択してください。
angular