Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

NestJS で Angularで作ったUIを表示する

More than 1 year has passed since last update.

(ちょっとしたこと) AngularでUIを作って、NestJSでREST APIと併せて公開するという使い方もあるので、そのやり方をまとめる。といっても、NestJSはExpress上で動いているようなものなので、やることは基本的にExpressと同じで、特に目新しいことはない。

Angular側の設定

Angularで作成したUIは、buildコマンドによってバンドルし、NestJSから見えるパスに生成する必要がある。生成先のパスはangular.jsonoutputPathで指定する。

angular.json
{
  "projects": {
  ...中略...
          "options": {
            "outputPath": "<NestJsプロジェクトの場所>/public等",

あとは、ng buildng build -wでビルドすればよい。

NestJSで静的ファイルのパスを指定する

生成したバンドルファイルを開けるようにするために、以下のように静的ファイルを置くパス(この場合はmain.ts基準の相対)で指定する。(参考:https://docs.nestjs.com/techniques/mvc)

main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { join } from 'path';

async function bootstrap() {
    const app = await NestFactory.create(AppModule);
    app.useStaticAssets(join(__dirname, '..', 'public'));
    await app.listen(3000);
}
bootstrap();

訂正: 以下の内容は不要

publicを公開した時点で、エンドポイントからindex.htmlを公開する必要はありませんでした…

コントローラから公開する

REST APIと同様、静的ファイルをGetメソッドから開けるようにするために、コントローラを追加する。実はこれには色々なやり方があるらしく、どれが良いのかはいまいちわからない。

方法1 ファイルを送信する

Res(応答オブジェクト)のsendFileメソッドを使ってファイルを返すという方法。なんとなく、そのまま返すという点で速そう。

以下は、ルートへのGETメソッドの応答に、index.htmlをそのまま送っている。

app.controller.ts
import { Controller, Get, Res } from '@nestjs/common';

@Controller()
export class AppController {
  constructor() {}

  @Get()
  root( @Res() res ) {
      res.sendFile( 'index.html' );
  }
}

方法2 レンダリングする

Angularのバンドル後のファイルであれば、この方法のメリットはあまりないと思うが、テンプレートエンジンを使ってレンダリングするという方法もある。

以下では、@Renderデコレータに、テンプレート(static直下のindex.html)を使ってレンダリングするよう設定することで、テンプレートエンジンを介してAngularのバンドル後のファイルを公開している。

普通は関数の本体(ここではroot())でテンプレートエンジンに与えるパラメータを返すのだが、Angularの生成したファイルに対して加工することはないので、root()では何もしていない。テンプレートエンジンを通している分、方法1と比べると若干遅いかもしれない…

app.controller.ts
import { Controller, Get, Render } from '@nestjs/common';

@Controller()
export class AppController {
  constructor() {}

  @Get()
  @Render('index.html')
  root() {}
}

実行結果

Angular CLIでサンプルを作成し、それをNestJSのサーバ(ポート:3000番)で公開すると、以下のような画面が表示される。

image.png

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away