CodeZine(コードジン)

特集ページ一覧

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

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

  • LINEで送る
  • このエントリーをはてなブックマークに追加
目次

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

 リスト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サーバーを実行するファイル

  • LINEで送る
  • このエントリーをはてなブックマークに追加

バックナンバー

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

もっと読む

著者プロフィール

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

    <WINGSプロジェクトについて> 有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂...

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

    静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for ASP/ASP.NET。執筆コミュニティ「WINGSプロジェクト」代表。 主な著書に「入門シリーズ(サーバサイドAjax/XM...

あなたにオススメ

All contents copyright © 2005-2021 Shoeisha Co., Ltd. All rights reserved. ver.1.5