このサイトは、只今WEB業界で活躍中のデザイナー、プログラマーの方々の情報を集めたweb統合情報サイトです。

Archives Details

Angular4 + SSR(サーバーサイドレンダリング)(Universal JavaScript)環境の最小最短 構築方法

Angular2

2017.10.08

この記事は最終更新日から1年以上が経過しています。

どもです。

今回は、Angular4で最小のSSR(サーバーサイドレンダリング または、Universal JavaScript, アイソモーフィックJavaScript)環境の構築方法です。

SSR(サーバーサイドレンダリング)とはなんぞや。

SSR(サーバーサイドレンダリング または、Universal JavaScript, アイソモーフィックJavaScript)とは、ざっくり言うと、初期表示をサーバー側(今回はexpressを使用)で表示させ、その後は通常のroutingを用いたSPAの処理を行う手法となります。

何が嬉しいかと言うと、最も得られる効果としては

・初期表示のHTMLはサーバー側で生成するので、高速化を図れる。

・フラグメント識別子の必要性がないので、SEO対策となる。

etc..(他にもありますが)

と、言ったところでしょうか。

当方も以前、angularJSでゲーム作成していた頃(今は、もっぱらVueJS)、こんな感じで初期表示はDOMの方にjsonを出力し、パフォーマンスを稼いでおりました。

var json = JSON.parse(apiPath);
angular.element(document).ready(function () {
  Homepage.app.value('data', json.data);
  angular.bootstrap(document, ['Homepage'])
});

PCサイトだと気にならないかもしれませんが、スマートフォンとなると回線も早くない場合もありますので、初期表示のパフォーマンスやレスポンス量などは重要視されていました。

なので、上記の方法等で回避していたこともありました。

と言った感じに、SSR(サーバーサイドレンダリング または、Universal JavaScript, アイソモーフィックJavaScript)周りの事を書き出すとキリがないかと思いますので、今回は詳細は書かきません。

Googleさんで検索などすると、色々と見つかりますので調べて頂ければと。><

まぁ、図で表すと以下の様に通常のSPAから、最初のレスポンス(1,2の手順)をクライアント側に持ってくる感じとなります。

それでは、早速構築していきましょう。

すぐに試したい方は

すぐに動かして見たい方はgithubの方にupしましたので、こちらを使って頂ければと。

Github

Angular 4 SSR (Universal) Starter

ng CLIを用いたアプリケーション作成

今回は、「ng CLI」を用いて環境構築を行っていきます。

ng CLI」をご存知でない方は、こちらの記事などを参照頂ければと思います。

ang4-ssr」という、アプリケーション名で生成します。

オプションで「routing」を付与します。

ng new ang4-ssr --routing

ディレクトリ移動

cd ang4-ssr

その他、必要なパッケージをnpm でinstallします。

npm install --save @angular/platform-server @angular/animations
npm install --save-dev webpack

「app.module.ts」ファイルの一部を修正します。

src/app/app.module.ts

imports: [
  BrowserModule,
  ...
],

imports: [
  BrowserModule.withServerTransition({appId: 'ang4-ssr'}),
  ...
],

BrowserModuleのwithServerTransitionメンバーを利用します。

server.module作成

新規で「app.server.module.ts」ファイルを作成します。

「@angular/platform-server」パッケージの「ServerModule」を使用します。

これを「NgModule」にimportするようにします。

src/app/app.server.module.ts

import { NgModule } from '@angular/core';
import { ServerModule } from '@angular/platform-server';
import { AppModule } from './app.module';
import { AppComponent } from './app.component';

@NgModule({
imports: [
  ServerModule,
  AppModule
],
bootstrap: [AppComponent]
})
export class AppServerModule { }
server.tsファイル作成

新規に「server.ts」ファイルを作成します。

「@angular/platform-server」パッケージから、「platformServer, renderModuleFactory」とそれぞれのモジュールを使用します。

サーバーは「express」を使用します。

src/server.ts

import 'reflect-metadata';
import 'zone.js/dist/zone-node';
import { platformServer, renderModuleFactory } from '@angular/platform-server';
import { enableProdMode } from '@angular/core';
import { AppServerModuleNgFactory } from '../dist/ngfactory/src/app/app.server.module.ngfactory';
import * as express from 'express';
import { readFileSync } from 'fs';
import { join } from 'path';

const PORT = 4000;

enableProdMode();

const app = express();

const template = readFileSync(join(__dirname, '..', 'dist', 'index.html')).toString();

app.engine('html', (_, options, callback) => {
  const opts = { document: template, url: options.req.url };

  renderModuleFactory(AppServerModuleNgFactory, opts)
    .then(html => callback(null, html));
});

app.set('view engine', 'html');
app.set('views', 'src');

app.get('*.*', express.static(join(__dirname, '..', 'dist')));

app.get('*', (req, res) => {
  res.render('index', { req });
});

app.listen(PORT, () => {
  console.log(`listening on http://localhost:${PORT}!`);
});

レンダリングを行うファイルは、distディレクトリを参照するようにします。

また、AppServerModuleNgFactoryモジュールが存在しない状態なので、以下の様にPATHエラーが発生しますので、ビルドを行えるように設定していきます。

tsconfig.app.json追加修正

tsconfig.app.jsonの”exclude”に「”server.ts”」追加修正行います。

src/tsconfig.app.json

"exclude": [
  "test.ts",
  "**/*.spec.ts"
]

"exclude": [
  "server.ts",
  "test.ts",
  "**/*.spec.ts"
]
tsconfig.json項目追加

tsconfig.jsonファイルに「”angularCompilerOptions”」を追加します。

compilerOptionsと同列に追加します。

/tsconfig.json

"angularCompilerOptions": {
  "genDir": "./dist/ngfactory",
  "entryModule": "./src/app/app.module#AppModule"
}
package.json、scripts修正

package.jsonのscriptsにデフォルトのコマンドが記述されていますが、これらを変更します。

/package.json

"scripts": {
  "ng": "ng",
  "start": "ng serve",
  "build": "ng build",
  "test": "ng test",
  "lint": "ng lint",
  "e2e": "ng e2e"
},

"scripts": {
  "prestart": "ng build --prod && ngc",
  "start": "ts-node src/server.ts"
},

と、一旦ここまで修正完了しましたら、起動してみましょう。

npm run start

expressサーバーが起動して、問題がなければ、localhostの4000番ポートで、サーバが立ち上がります。

ブラウザで「http://localhost:4000」をアクセスします。

http://localhost:4000

上記の様に確認できればオッケーです。

ng ジェネレートコマンドで、ページ作成

それでは、ページが変わるとmetaが変更出来るように修正していきましょう。

ctrl + c 等で、一旦サーバーを止めて、「ng generate」コマンドでページ作成の一式を作成します。

ng g c home --module=app.module.ts
ng g c about --module=app.module.ts

ng generate」コマンドで「about」「home」を作成したところ。

app-routing.module.tsファイル追加修正

app-routing.module.tsに追加修正を行っていきます。

先程、「ng generate」コマンドで生成した「about」「home」のcomponentをimportし、ルーティングに追加します。

app-routing.module.ts

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { AboutComponent } from './about/about.component';
import { HomeComponent } from './home/home.component';

const routes: Routes = [
  {
    path: '',
    component: HomeComponent
  },
  {
    path: 'about',
    component: AboutComponent
  }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }
app.component.html修正

デフォルトでは、app.component.htmlに色々と記述されていますが、削除してページ遷移出来るように修正します。

app.component.html

<ul>
 	<li><a>Home</a></li>
 	<li><a>About</a></li>
</ul>
home.component.ts修正

home.component.tsを修正していきます。

‘@angular/platform-browser’パッケージの「Meta」と「Title」をimportします。

これらはそれぞれ、Titleやmetaを扱うためのAPIが用意されているので、こちらを用いてTitleやmetaを変更出来る様に設定していきます。

descriptionが増え続けない様に、meta.removeTagで一旦初期化を行い、追加しております。

src/app/home/home.component.ts

import { Component, OnInit } from '@angular/core';
import { Meta, Title } from '@angular/platform-browser';

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {

  constructor(meta: Meta, title: Title) {

    title.setTitle('Angular4 SSR');

    meta.removeTag('name=description');

    meta.addTags([
      {
        name: 'author', content: 'webcyou.com'
      },
      {
        name: 'keywords', content: 'Angular 4 SSR tutorial'
      },
      {
        name: 'description', content: 'Angular4のSSR環境チュートリアルです'
      },
    ]);

  }

  ngOnInit() {
  }

}
about.component.ts修正

同様にabout.component.tsを修正します。

こちらでは、title.setTitle(‘Angular4 SSR – aboutページ’)と、descriptionが変更出来るようにします。

src/app/about/about.component.ts

import { Component, OnInit } from '@angular/core';
import { Meta, Title } from '@angular/platform-browser';

@Component({
  selector: 'app-about',
  templateUrl: './about.component.html',
  styleUrls: ['./about.component.css']
})
export class AboutComponent implements OnInit {

  constructor(meta: Meta, title: Title) {

    title.setTitle('Angular4 SSR - aboutページ');

    meta.removeTag('name=description');

    meta.addTags([
      {
        name: 'description', content: 'aboutページのdescription'
      },
    ]);

  }

  ngOnInit() {
  }

}

と、これで、完了となります。

それでは、確認していきましょう!

npm start

ブラウザで「http://localhost:4000」をアクセスします。

各リンクをクリックすると各ページへと遷移ができ、確認できます。

webインスペクタ等で、metaを確認

Homeページ

Aboutページ

metaタグが変更しているのが確認できました!

最後に

と言った感じで、Angular4で最小のSSR(サーバーサイドレンダリング または、Universal JavaScript, アイソモーフィックJavaScript)環境の構築方法でした。

Angular4はフルスペックなフレームワークな故に容量も大きいところがありますが、パッケージなども公式で揃っている点から「一つ一つパッケージを選択する」と言った手順も減ることから、比較的簡単に環境を構築することができる点が良かったりしますね。

今回のソースはこちらにありますので、宜しければと。

Github

Angular 4 SSR (Universal) Starter

 

ではではぁ。

Comment

Related Article

Angular 「スマホ・PC」でcomponentとCSSを切り替える(分岐させる)方法

2017.10.15

Angular4 + SSR(サーバーサイドレンダリング)(Universal JavaScript)環境の最小最短 構築方法

2017.10.08

Rails5 APIモード + Angular SPA環境 爆速構築の手順 その2。

2017.04.19

Rails5 APIモード + Angular SPA環境 爆速構築の手順 その1。

2017.04.10

Angular CLIで、Angularアプリをかんたん楽々構築!

2017.04.09

Angular2の始め方。Angular2 公式チュートリアル – HTTP(簡単な和訳)

2017.04.09

Angular2の始め方。Angular2 公式チュートリアル – Routing(簡単な和訳)

2017.04.06

Angular2の始め方。Angular2 公式チュートリアル – Services(簡単な和訳)

2017.04.03

Angular2の始め方。Angular2 公式チュートリアル – Multiple Components(簡単な和訳)

2017.04.03

Angular2の始め方。Angular2 公式チュートリアル – Master/Detail(簡単な和訳)

2017.01.20

CATEGORY LIST

LATEST NEWS

Rust - Actix Web mongo ユーザー登録 JWT認証

Rust

2024.03.24

Rust - Actix Web JWT 認証認可 APIの作成

Rust

2024.02.25

Rust - Actix Web × JSON 静的ファイルをAPIで返却

Rust

2024.01.19

Rust - Actix Web × MongoDB環境をサクッと起動

Rust

2024.01.18

5分で学ぶ RustでWave Function Collapse (波動関数崩壊アルゴリズム)

Rust

2024.01.15

LLaMAモデル GGMLフォーマット(llama.cpp)をRustフレームワーク Leptosを用いて M1MacMiniでサクッと動かす。

Rust

2024.01.11

2024年 狙っているモバイルノートPC

tool

2024.01.07

MacOS XcodeにSDL2を追加

tool

2023.12.26

php 7.4にアップデート

PHP

2023.12.24

5分で覚える Flutter Flameで作る Wave Function Collapse - 波動関数崩壊アルゴリズム

AI・Bot・algorithm

2023.12.20

Flutter - Flameでゲーム作成 (キャラクターの移動)

Flutter

2023.07.23

Flutterで作る ChatGPT Prompt Manager

Flutter

2023.07.12

RANKING

Follow

SPONSOR

現在、掲載募集中です。



Links

About Us

WEBデザイナーの、WEBデザイナーによる、WEBデザイナーの為のサイト。「みんなで書こう!」と仲間を募ってみたが、結局書くのは自分だけとなってしまいました。日々のメモを綴っていきます。

Entry Profile

Graphical FrontEnd Engineer
- Daisuke Takayama

MAD CITY 北九州市で生まれ育つ。20代はバンド活動に明け暮れ、ふと「webデザイナーになりたい。」と思い、デジタルハリウッド福岡校入学。卒業後、数々の賞を受賞、web業界をざわつかせる。
現在、主に、ゲーム制作中心に港区六本木界隈で活動中。

FOLLOW US