スクリーンショット_2019-06-28_18

Nuxt.jsとNest.jsで表裏TypeScriptな環境をつくる(2.バックエンド編)

前回 の続き。次はサーバサイドの実装をして、フロントからデータを取得するまでをおこなってみる。

Nest.jsとは

Nest.jsはNode.jsのフレームワークの一つ。Nodeのフレームワークといえば、Expressが一番人気だが、Nest.jsはAngularライクな記法とTypeScriptを使用して構築されていることから、人気が少しずつ出てきている。

個人的に押したい部分はDocの豊富さとAngularライクに構成を固めているところ。
Doc: https://docs.nestjs.com/

基本的な記法やNest.jsで扱うことができる機能、サポートしているライブラリ群(GraphQL、TypeORM、Passport等)のレシピなど、しっかりと内容が記載されているため、機能追加したいときなどはDocを見れば基本的なものはだいたい揃っている。

Angularライクに controllermoduleservicepipeなどの構成を取る。
また、@nestjs/cli があり、下記のような感じで容易にscaffoldを生成することができる。

src
|- app.controller.ts
|- app.module.ts
|- app.service.ts
|- main.ts

実装

versionは以下の通り。

Node.js: v10.16.0
@nestjs/cli: v6.5.0

まずは、@nestjs/cli をインストールし、雛形を作成する。

npm i -g @nestjs/cli
nest new <project-name> # project-nameがディレクトリ名になる

すると、いい感じにファイルを作成してくれる。

すでに雛形が揃っているので、実行可能。

npm run start

Nest周りの諸々設定

Hot Reload (Webpack)

公式に乗っているとおりだが、順にやってみる。
まずはwebpack関連の必要なものを一式インストールする。

npm i --save-dev webpack webpack-cli webpack-node-externals ts-loader

次に、webpackの設定ファイルを追加。

# webpack.config.js
const webpack = require('webpack');
const path = require('path');
const nodeExternals = require('webpack-node-externals');

module.exports = {
 entry: ['webpack/hot/poll?100', './src/main.ts'],
 watch: true,
 target: 'node',
 externals: [
   nodeExternals({
     whitelist: ['webpack/hot/poll?100'],
   }),
 ],
 module: {
   rules: [
     {
       test: /.tsx?$/,
       use: 'ts-loader',
       exclude: /node_modules/,
     },
   ],
 },
 mode: 'development',
 resolve: {
   extensions: ['.tsx', '.ts', '.js'],
 },
 plugins: [new webpack.HotModuleReplacementPlugin()],
 output: {
   path: path.join(__dirname, 'dist'),
   filename: 'server.js',
 },
};

src/main.ts を以下のように修正。
(フロントと被らないようにportもついでに変えておく。また、CORS用にオプションを追加する。)

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

declare const module: any;

async function bootstrap() {
 const app = await NestFactory.create(AppModule, { cors: true });
 await app.listen(4000);
 if (module.hot) {
   module.hot.accept();
   module.hot.dispose(() => app.close());
 }
}
bootstrap();

package.json のscriptを修正。

"start": "node dist/server",
"webpack": "webpack --config webpack.config.js"

ここまでできたら、webpackでファイル監視を開始。

npm run webpack

監視が開始されたら、別ターミナルで実行。

npm run start

この状態で src/app.service.ts のgetHello()の文字列を適当に書き換えてHMRされていればおけ。

データをサーバ側で作成し、フロントに渡す

フロントと同様に、Userの型定義を作成する。

# src/app.interface.ts

export interface User {
 id: number
 name: string
 age: number
}

次に、上記をベースにベタ書きでデータを作成し、APIを修正していく。

# src/app.service.ts

import { Injectable } from "@nestjs/common";
import { User } from "./app.interface";

// getHello()を削除し、getProfile()を追加
@Injectable()
export class AppService {
 getProfile(): User[] {
   return [
     {
       id: 3,
       name: "Nest太郎",
       age: 24,
     },
     {
       id: 4,
       name: "Nest二郎",
       age: 21,
     },
   ];
 }
}
# src/app.controller.ts

import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';

@Controller()
export class AppController {
 constructor(private readonly appService: AppService) {}

 @Get()
 getProfile(): any {
   return this.appService.getProfile();
 }
}

フロント側の修正

最後に、サーバ側からデータを取るようにフロントを修正する。

npm i --save axios

フロントでベタ書きだったデータ部分をaxiosで拾ってくるように変更する。

# pages/profile.vue

export default class ProfilePage extends Vue {
 users: User[] = [];
 async created() {
   const res = await axios.get("http://localhost:4000/");
   this.users = res.data;
 }
}

もう一度 localhost:3000/profile を見てみる。

無事に取得できた。

まとめ

フロントもバックもTSにすることで、記法の違いが減り負担が減る気がする。何よりやってみて思ったが、TSの補完機能が素晴らしい。

さくっとWEBアプリを作る上での負担は非常に少なそうなため、この構成でなにか作ってみたい。

最近は、Node.jsの創始者であるRyan Dahl がdeno というサーバサイドTSランタイムを公表し活発に更新が進んでいるっぽい。

Major features necessary for 1.0

denoのエコシステムが発展したら、よりTSで書く機会も増えてくると思うのでキャッチアップを続けたい。

今回の最終的なコード: https://github.com/daitasu/nuxt-nest-app
フロント側の実装はこちら:  
Nuxt.jsとNest.jsで表裏TypeScriptな環境をつくる(1. フロント編)

この記事が気に入ったらサポートをしてみませんか?