のらねこの気まま暮らし

技術系だけど、Qiita向きではないポエムとかを書くめったに更新されないヤツ

App Engineを試す vol2 ~NuxtをAppEngineで動かす~

vol2 NuxtをAppEngineで動かす

概要

この記事ではAppEngineのデフォルトサービスでNuxtを動かすまでの手順を解説します。

背景

AppEngineが便利っていう話を聞いたので、AppEngineでどこまでできるのかを試す連載。 連載のゴールとしては、NuxtをBFFとしておいてAPIで処理を行うというマルチサービスの構成。

ローカルマシンにnode v10.16をインストール

nodenvを使ってるけどお好きなのでどうぞ。

> nodenv install 10.16.0
> nodenv local 10.16.0

プロジェクトの初期化

> npm init

nuxtのセットアップ

Expressで連携させたいので一旦手動でnuxtを入れますよ。 create-nuxt-appを使いたい方は作成してからよしなに調整するのじゃ。

> npm install --save nuxt

ソースの作成

以下のファイルを用意する。

  • nuxt.config.js
  • nuxt/pages/index.vue
> cat nuxt.config.js
module.exports = {
  srcDir: "./nuxt"
}
> mkdir -p nuxt/pages
> cat nuxt/pages/index.vue
<template>
  <p>hello world!</p>
</template>

起動コマンドを指定して、動作確認

取り替えず開発用にビルドできるようにする

diff --git a/package.json b/package.json
index b493bb3..d3dc0a3 100644
--- a/package.json
+++ b/package.json
@@ -4,6 +4,7 @@
   "description": "",
   "main": "index.js",
   "scripts": {
+    "start": "nuxt dev",
     "test": "echo \"Error: no test specified\" && exit 1"
   },
   "author":  

起動する。

> npm start

動作を確認する。

curl http://localhost:3000/

AppEngineへのdeploy

一旦この段階でAppEngineにdeployしてみる。 app.yamlを最低限の構成で追加する。

> cat app.yaml
runtime: nodejs10

devのままだと動かないので、startに変更。

diff --git a/package.json b/package.json
index d3dc0a3..0c2ac81 100644
--- a/package.json
+++ b/package.json
@@ -4,7 +4,8 @@
   "description": "",
   "main": "index.js",
   "scripts": {
-    "start": "nuxt dev",
+    "start": "nuxt start",
+    "build": "nuxt build",
     "test": "echo \"Error: no test specified\" && exit 1"
   },
   "author": "",

ローカルでビルドしておく。

> npm run build

Let's deploy

> gcloud app deploy

deploy後、gcloud app browseでページを開いてみると、 Nuxtで実装したページがホスティングされたのがわかります。

Expressでハンドルする。

Nuxtが動いたので記事タイトル的にはOKなんですけど、最終的にはバックエンドでAPIと通信したいのです。 そのためにはBFFと連携するバックエンド部分の実装が必要なのです。

そこをお手軽にExpressで作っちゃいます。

Expressのエントリポイントを作成し、Nuxtをバンドルするようにします。 /messageはExpressで処理されているのをわかりやすく確認するために追加したルートです。

> cat app.js
'use strict';

const express = require('express');

const app = express();
const { Nuxt, Builder } = require('nuxt')

// Nuxt.js をオプションとともにインスタンス化する
const config = require('./nuxt.config')
config.dev = process.env.NODE_ENV !== 'production'
const nuxt = new Nuxt(config)

app.get('/message', (req, res) => {
  res
    .status(200)
    .send('Hello, world!')
    .end();
});

app.use(nuxt.render)

// Start the server
if (config.dev) {
  // hot-reload for development
  new Builder(nuxt).build().then(listen)
} else {
  // for production
  listen()
}

function listen() {
  const PORT = process.env.PORT || 8080;
  app.listen(PORT, () => {
    console.log(`App listening on port ${PORT}`);
    console.log('Press Ctrl+C to quit.');
  });
}

module.exports = app;

npm startでexpressのエントリポイントを実行するように変更します

diff --git a/package.json b/package.json
index 0c2ac81..a616d33 100644
--- a/package.json
+++ b/package.json
@@ -4,7 +4,7 @@
   "description": "",
   "main": "index.js",
   "scripts": {
-    "start": "nuxt start",
+    "start": "node app.js",
     "build": "nuxt build",
     "test": "echo \"Error: no test specified\" && exit 1"
   },

さあ、デプロイしましょう。

> npm run build
> gcloud app deploy

gcloud app browseで変わらずにNuxtのページが表示されていることが確認できます。 Expressに追加したルートが動いているかも確認しましょう。

> curl https://astral-web-260712.appspot.com/message
Hello, world!%

実行できていますね! これで今日の目標は達成ですっ

次回予告

なんとなくBFFとしてのサービスが動きそうなことが確認できたので、 明日はAPIサーバ用のサービスを作ってみます!