Nuxt.jsを使ってWebアプリ作ってみようかなーと思って、環境を作った時の手順を備忘録として残しておきます。
各種バージョン
$ node -v
v12.16.3
$ npm -v
6.14.4
$ nest -v
7.6.0
環境構築
フロントとバックエンドを別プロジェクトで作成して、モノリポで管理するためLernaでプロジェクトを作成します。
$ mkdir web-sample
$ cd web-sample
$ lerna init
lerna notice cli v4.0.0
lerna info Initializing Git repository
lerna info Creating package.json
lerna info Creating lerna.json
lerna info Creating packages directory
lerna success Initialized Lerna files
フロント/バックエンドのプロジェクト作成
$ cd packages
# フロントエンド作成
$ npx create-nuxt-app front
create-nuxt-app v3.6.0
✨ Generating Nuxt.js project in front
? Project name: front
? Programming language: TypeScript
? Package manager: Npm
? UI framework: Element
? Nuxt.js modules: (Press <space> to select, <a> to toggle all, <i> to invert se
lection)
? Linting tools: (Press <space> to select, <a> to toggle all, <i> to invert sele
ction)
? Testing framework: None
? Rendering mode: Universal (SSR / SSG)
? Deployment target: Static (Static/Jamstack hosting)
? Development tools: (Press <space> to select, <a> to toggle all, <i> to invert
selection)
? What is your GitHub username? teracy55
? Version control system: Git
# バックエンド生成
$ nest new server
⚡ We will scaffold your app in a few seconds..
CREATE server/.eslintrc.js (631 bytes)
CREATE server/.prettierrc (51 bytes)
CREATE server/README.md (3339 bytes)
CREATE server/nest-cli.json (64 bytes)
CREATE server/package.json (1968 bytes)
CREATE server/tsconfig.build.json (97 bytes)
CREATE server/tsconfig.json (339 bytes)
CREATE server/src/app.controller.spec.ts (617 bytes)
CREATE server/src/app.controller.ts (274 bytes)
CREATE server/src/app.module.ts (249 bytes)
CREATE server/src/app.service.ts (142 bytes)
CREATE server/src/main.ts (208 bytes)
CREATE server/test/app.e2e-spec.ts (630 bytes)
CREATE server/test/jest-e2e.json (183 bytes)
? Which package manager would you ❤️ to use? npm
✔ Installation in progress... ☕
🚀 Successfully created project server
👉 Get started with the following commands:
$ cd server
$ npm run start
Thanks for installing Nest 🙏
Please consider donating to our open collective
to help us maintain this package.
🍷 Donate: https://opencollective.com/nest
サーバー側修正
ローカル環境ではフロント側もNuxt.jsのサーバー機能使って別サーバーとして起動させるため、CORSを許可します
server/src/main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
const env = process.env.NODE_ENV || 'develop';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
if (env === 'develop') {
app.enableCors();
}
await app.listen(3000);
}
bootstrap();
フロント側修正
Nuxt.jsの起動ポートを変える
Nuxt.jsのデフォルトポートが3000となっていて、NestJSのポートと被るためポートを変更します。
※本番ではビルドしたHTMLを静的ファイルとして公開するため関係ないです
front/nuxt.config.js
server: {
port: 8000,
},
axiosの設定
API呼び出しのためにaxiosをインストールします
参考:https://axios.nuxtjs.org/setup
$ npm install @nuxtjs/axios
front/nuxt.config.js
modules: [
'@nuxtjs/axios'
],
front/tsconfig.json
"types": [
"@nuxt/types",
"@nuxtjs/axios",
"@types/node"
]
コンポーネントの修正
front/pages/index.vue
<template>
<div class="container">
<div>
<Logo />
<h1 class="title">
front
</h1>
{{title}}
・・・
</template>
<script lang="ts">
import Vue from 'vue';
export default Vue.extend({
data() {
return {
title: '',
}
},
async mounted() {
this.title = await this.getMessage();
},
methods: {
getMessage(): Promise<string> {
return this.$axios.$get('http://localhost:3000');
}
}
})
</script>
起動する
ターミナルを2つ開きます
- サーバー側を起動
cd packages/server
npm run start:dev
- フロント側を起動
cd packages/front
npm run dev
-
localhost:8000
にアクセスします
ちゃんとサーバーから取得したHello World!
が表示されました!
本番向け
本番環境ではフロント/バックエンド共にトランスパイルしたJSで動かしたいので、手を加えます
バックエンド側を修正
- フロント側の静的ファイルへのルーティングを設定
$ npm install --save @nestjs/serve-static
- フロント側のビルドファイルは
packages/front/dist
に出力されるため、app.module.tsからの相対パスで指定します
server/src/app.module.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ServeStaticModule } from '@nestjs/serve-static';
import { join } from 'path';
@Module({
imports: [
ServeStaticModule.forRoot({
rootPath: join(__dirname, '../../front/', 'dist'),
}),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
- APIのURLを
/api
ではじまるようにグローバルプレフィクスを設定します
server/src/main.ts
const app = await NestFactory.create(AppModule);
app.setGlobalPrefix('api');
- フロント側と本番ビルド用のスクリプト名を合わせます
server/package.json
"build:prod": "npm run build",
フロント側を修正
- APIのURLを変更します
front/pages/index.vue
methods: {
getMessage(): Promise<string> {
return this.$axios.$get('http://localhost:3000/api');
}
}
- バックエンド側と本番ビルド用のスクリプト名を合わせます
front/package.json
"build:prod": "npm run generate",
本番ビルド
- lernaコマンド使って一括で本番ビルドします
$ lerna run build:prod
lerna notice cli v4.0.0
lerna info Executing command in 2 packages: "npm run build:prod"
lerna info run Ran npm script 'build:prod' in 'server' in 14.2s:
> server@0.0.1 build:prod /Users/terashimahiroshi/Desktop/dev/web-sample/packages/server
> npm run build
> server@0.0.1 prebuild /Users/terashimahiroshi/Desktop/dev/web-sample/packages/server
> rimraf dist
> server@0.0.1 build /Users/terashimahiroshi/Desktop/dev/web-sample/packages/server
> nest build
lerna info run Ran npm script 'build:prod' in 'front' in 27.9s:
> front@1.0.0 build:prod /Users/terashimahiroshi/Desktop/dev/web-sample/packages/front
> npm run generate
> front@1.0.0 generate /Users/terashimahiroshi/Desktop/dev/web-sample/packages/front
> nuxt generate
ℹ Doing webpack rebuild because nuxt.config.js modified
ℹ Production build
ℹ Bundling for server and client side
ℹ Target: static
ℹ Using components loader to optimize imports
ℹ Discovered Components: node_modules/.cache/nuxt/components/readme.md
✔ Builder initialized
✔ Nuxt files generated
ℹ Compiling Client
✔ Client: Compiled successfully in 16.57s
ℹ Compiling Server
✔ Server: Compiled successfully in 2.14s
ℹ Full static generation activated
ℹ Generating output directory: dist/
ℹ Generating pages with full static mode
✔ Generated route "/"
✔ Client-side fallback created: 200.html
✔ Static manifest generated
lerna success run Ran npm script 'build:prod' in 2 packages in 27.9s:
lerna success - front
lerna success - server
サーバー起動
cd packages/server
npm run start:prod
-
localhost:3000
にアクセスするとフロント側の画面が表示されます- ※本番はNestJS側のポート(3000)なので注意