SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

次世代Webアプリケーションフレームワーク「Angular」の活用

SEO対策やページ表示速度アップに有効!「Angular」のサーバーサイドレンダリング

次世代Webアプリケーションフレームワーク「Angular」の活用 第19回

サーバーサイドレンダリングの実装

 リスト1のコマンドを実行すると、図5に示すファイルが追加/変更されます。サーバーサイドレンダリングを実現するこれらの実装について、以下で概要を説明します。

図5:リスト1のコマンドで追加/変更されるファイル(p001-basic-ssr)
図5:リスト1のコマンドで追加/変更されるファイル(p001-basic-ssr)

サーバーサイドレンダリング対応で追加されるファイル

 まず、追加されるファイルを表1に示します。サーバーサイドレンダリングの本質的な実装はNo.1~3で、No.4と5はビルド用の設定ファイルです。

表1:サーバーサイドレンダリング対応で追加されるファイル
No. ファイル名  役割 
1 app.server.module.ts サーバーサイドのルートモジュール
2 main.server.ts サーバーサイドのルートモジュールをエクスポートする実装
3 server.ts Express Webサーバーの実装
4 webpack.server.config.ts サーバーサイド実装のwebpack設定
5 tsconfig.server.json サーバーサイド実装のTypeScript設定

 No.1のapp.server.module.tsは、サーバーサイドレンダリングされるWebページのルートモジュールです。

[リスト3]サーバーサイドレンダリングのルートモジュール(p001-basic-ssr/src/app/app.server.module.ts)
@NgModule({
  imports: [
    AppModule,    // Webページのルートモジュール ...(1)
    ServerModule, // サーバーサイドレンダリングのモジュール ...(2)
  ],
  bootstrap: [AppComponent],
})
export class AppServerModule {}

 元のWebページのルートモジュールAppModule(1)に加えて、サーバーサイドレンダリング機能を提供するServerModule(2)をインポートします。ここで定義したAppServerModuleクラスは、No.2のmain.server.tsで、リスト4の通りエクスポート(公開)されます。

[リスト4]サーバーサイドレンダリングのルートモジュールを公開する実装(p001-basic-ssr/src/main.server.ts)
export { AppServerModule } from './app/app.server.module';

 No.3のserver.tsは、Node.js上で実行できるWebサーバー「Express」を利用してWebページをホストする実装です。Expressの詳細は公式ページも参考にしてください。サーバーサイドレンダリングに関連する実装をリスト5に示します。

[リスト5]ExpressでAngularのWebページをホストする実装(p001-basic-ssr/server.ts)
app.engine('html', ngExpressEngine({   // ...(1)
  bootstrap: AppServerModuleNgFactory, // ...(2)
  providers: [
    provideModuleMap(LAZY_MODULE_MAP)  // ...(3)
  ]
}));

 (1)の「app.engine」は、Webページを生成するプログラム(テンプレートエンジン)を指定するExpressのメソッドです。ここで、Angular Universalが提供するテンプレートエンジンngExpressEngineを指定すると、ExpressでAngularのサーバーサイドレンダリングを利用できるようになります。

 ngExpressEngineのbootstrap引数(2)には、リスト3、4で実装したAppServerModule(がビルド時に変換されるAppServerModuleNgFactory)を指定します。providers引数には、サーバーサイドで利用するモジュールやサービスなどの設定を記述します。

[補足]モジュールの遅延ロードとサーバーサイドレンダリング

 リスト5(3)は、クライアントサイド実行時にルーターの機能で遅延ロードされるモジュールを、サーバーサイドで実行できるようにする設定です。モジュールの遅延ロードについては、公式ドキュメントも参考にしてください。

 この設定を有効にする場合、リスト3のAppServerModuleで、ModuleMapLoaderModuleをインポートします。記事執筆時点では、リスト1のコマンドで生成するapp.server.module.tsにインポート記述が含まれないため、手動で追加する必要があります。

[リスト6]app.server.module.tsで、ModuleMapLoaderModuleをインポートする記述
imports: [
  AppModule,
  ServerModule,
  ModuleMapLoaderModule // 追加でインポート
],

 遅延ロードされるモジュールがない場合は、リスト5(3)やリスト6の記述がなくても、正常にサーバーサイドレンダリングが動作します。

[補足]ngExpressEngineの内部で実行されるrenderModuleFactoryメソッド

 リスト5(1)のngExpressEngineは、Angularでサーバーサイドレンダリングを実行してHTML文字列を生成するrenderModuleFactoryメソッドを内部で実行します。renderModuleFactoryメソッドの詳細は、Angularの公式ドキュメントを参照してください。

サーバーサイドレンダリング対応で変更されるファイル

 次に、変更されるファイルを表2に示します。以下ではポイントとなる変更点を抽出して説明していきます。詳細はサンプルコードを参照してください。

表2:サーバーサイドレンダリング対応で変更されるファイル
No. ファイル名  変更内容    
1 app.module.ts BrowserModuleの設定変更(後述)
2 package.json パッケージ追加、スクリプト定義追加(後述)
3 package-lock.json パッケージ追加
4 angular.json サーバーサイド実装のビルド設定追加
5 main.ts  クライアントサイド処理の開始タイミングをページロード後(DOMContentLoadedイベント発生時)に変更

 No.1のapp.module.tsは、クライアントサイドで実行されるWebページのルートモジュールです。BrowserModuleにwithServerTransitionメソッドを追加して、サーバーサイドレンダリングのページからクライアントサイドの(通常の)ページに切り替える指定を追加します。「appId: 'serverApp'」はWebページを一意に識別するIDの指定です。

[リスト7]クライアントサイドWebページのルートモジュール(p001-basic-ssr/src/app/app.module.ts)
@NgModule({
(略)
  imports: [
//  BrowserModule // 変更前
    BrowserModule.withServerTransition({ appId: 'serverApp' }) // 変更後
  ],
(略)
})
export class AppModule { }

 また、No.2のpackage.jsonには、サーバーサイドレンダリングに関連した表3のスクリプト定義が追加されます。「npm run <スクリプトのキー>」コマンドで実行できます。

表3:サーバーサイドレンダリングに関連したスクリプト定義
No. スクリプトのキー 処理内容    
1 build:ssr サーバーサイドレンダリング用のビルド
2 serve:ssr WebページをホストするWebサーバーを起動
3 build:client-and-server-bundles  クライアントとサーバーのファイルをビルド
4 compile:server Express Webサーバーの実装をビルド

 サーバーサイドレンダリングを有効にしてアプリを実行するには、No.1のスクリプトを実行してビルド後、No.2のスクリプトでWebサーバーを起動します。No.1のビルド処理は、内部的にNo.3とNo.4を呼び出して、クライアント/サーバーのアプリファイルとWebサーバーの実装をすべてビルドするようになっています。

 ビルドされたファイルは、distフォルダー配下に、表4の通り出力されます。

表4:サーバーサイドレンダリングのビルドで出力されるファイル
No.  出力先    内容
1 dist/browser クライアントサイドで実行されるファイル群
2 dist/server サーバーサイドで実行されるファイル群
3 dist/server.ts ExpressでWebサーバーを実行するファイル

次のページ
サーバーサイドレンダリングの機能制限

この記事は参考になりましたか?

次世代Webアプリケーションフレームワーク「Angular」の活用連載記事一覧

もっと読む

この記事の著者

WINGSプロジェクト  吉川 英一(ヨシカワ エイイチ)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。 2026年時点での登録メンバは約50名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるLaravel実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/11444 2019/03/18 11:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー