LoginSignup
3
3

More than 5 years have passed since last update.

Angular Universal の Web サーバを Express でサクッと作る方法

Posted at

概要

Angular Universal の Web サーバ部分を、簡単な疎通など確認するためにとりあえずサクッとコピペするための備忘録

前提

以下の必要なモジュールは、型定義ファイル(@types/* でインストール)含めインストールされていること

  • express
  • express-engine
  • @nguniversal/express-engine
  • @nguniversal/module-map-ngfactory-loader

Express で Web サーバを作成

以下の通り、Express を使って Web サーバを作成する

server/web-server.ts
// 以下の2インポートは最初に呼ばれる必要がある
import 'zone.js/dist/zone-node';
import 'reflect-metadata';

import * as express from 'express';
import { join } from 'path';
import { ngExpressEngine } from '@nguniversal/express-engine';
import { provideModuleMap } from '@nguniversal/module-map-ngfactory-loader';

const webServer = express();
const PORT = process.env.PORT || 3000;
const CLIENT_DIST_PATH = join(process.cwd(), 'dist/demo-app'); // TODO: パスをビルド先フォルダ名に合わせる
// 動的に生成される dist ファイルため、require() のままにしておく
const { AppServerModuleNgFactory, LAZY_MODULE_MAP } = require(join(process.cwd(), 'dist/demo-app-server/main')); // TODO: パスをビルド先フォルダ名に合わせる

// テンプレートファイル名で拡張子が省略された場合のデフォルト拡張子を設定
webServer.set('view engine', 'html');
// テンプレートファイルを置くパスを設定
webServer.set('views', CLIENT_DIST_PATH);
// レンダリングに利用するテンプレートエンジンに Angular Express エンジン を登録
webServer.engine('html', ngExpressEngine({
  bootstrap: AppServerModuleNgFactory,
  providers: [ provideModuleMap(LAZY_MODULE_MAP) ]
}));
// サーバサイドレンダリングされる静的ファイル
webServer.get('*.*', express.static(CLIENT_DIST_PATH));

// 全ての API ルートは このルーティングを使用
webServer.use('/api/*', (req, res) => {
  console.log('[API が呼び出されました]');
  const response = { test1: 'aaa', test2: 'bbb' };
  res.status(200).send(response);
});

// 全ての通常ルートは Universal エンジンを使用
webServer.get('*', (req, res) => {
  console.log('[通常ルートが呼び出されました]');
  res.render('index', { req, res });
});

// Node サーバ開始
webServer.listen(PORT, () => {
  console.log(`Node server is listening - http://localhost:${PORT}`);
});

起動確認

起動スクリプト修正

以下のとおりに、package.json のスクリプトを修正

package.json
:
  "scripts": {
    "start": "node ./dist/server/web-server.js",
    "build": "npm run build:client && npm run build:server",
    "build:client": "ng run demo-app:app-shell:production",
    "build:server": "tsc --project server --outDir dist --allowjs true",
  },
:

以下のコマンドでビルド、アプリ起動

# ビルド
npm run build

# 起動
npm run start

以下の点をチェックし、問題なく動いていればOK。

  • ビルド完了後、以下のディレクトリと中身がルートディレクトリ配下に生成されているか
    • dist/common(クラサバ共用ファイル群)
    • dist/demo-app(クライアントのソースコード)
    • dist/demo-app-server(Universal 対応で作ったやつ)
    • dist/server(Express および API ロジック用ファイル群)
  • Web ブラウザにアクセスし、以下の挙動が行われるか
    • http://localhost:3000 でアクセスするとホーム画面が表示され、コンソールには [通常ルートが呼び出されました] と標準出力される
    • http://localhost:3000/api/aaa でアクセスすると、画面に {"test1":"aaa","test2":"bbb"} と表示され、コンソールには [API が呼び出されました] と標準出力される
    • http://localhost:3000/api でアクセスすると、URLは http://localhost:3000 となり、画面は何かしらの HTML で画面表示がなされ、コンソールには何かしらのエラーログが標準出力される(存在しないページへのアクセスエラー)
3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3