Web系エンジニアのアウトプット練習場

エンジニアリングと書評が中心。たまに全然関係無い話もします。

Nuxt.jsプロジェクトのデプロイ方法について

Google App Engineへのデプロイ方法を追記(2020/01/18)

最近、Nuxt.jsを趣味でよく触るのですが、いざデプロイしてみようと思ったところ、提示されている様々なデプロイ方法のうち、どの方法を選べば良いかがわからず悩まされました。
その際、私が考えたNuxt.jsのデプロイ方法選定の考え方を共有させていただきます。

Nuxt.jsのデプロイでお悩みの皆様のお役に立てれば幸いです。

デプロイの選択肢

Nuxtのデプロイ方法は、以下の2つがあります。

  • nuxt generateで静的ファイルを生成してデプロイする方法
  • Node.jsアプリとしてデプロイする方法

静的ファイルを生成してデプロイ

すべてのルートをプレレンダリングして予め静的ファイルを生成するため、SEOやページ表示速度面で有利な他、nuxt generateコマンドによって生成されたdistディレクトリをアップロードするだけで配信を開始できます。

また、NetlifyFirebase Hostingといった静的コンテンツ、動的コンテンツ向けの高速で安全性の高いホスティングサービスを利用することができます。

デプロイの作業としては、以下のコマンドでdistディレクトリに静的ファイルを出力して、distディレクトリの中身をドキュメントルートに配置するだけで完了です。

# nuxt generateをyarn経由で実行
$ yarn run generate

Netlifyを使用する場合は、GitHubと連携し、上記の作業をいとも簡単に自動化できます。

Netlify へデプロイするには? - NuxtJS

静的ファイルを生成してデプロイする方法の問題点

このデプロイ方法の問題点の1つは、動的なルーティングに対応できないことです。

例えば、ブログアプリにて、投稿ごとにposts/:idというようなページが欲しい場合は、nuxt.config.jsにて、あらかじめ投稿ごとにプリレンダする処理を書く必要があります*1

module.exports = {
  generate: {
    routes () {
      return axios.get(apiBaseUrl + "posts")
        .then((response) => {
          return response.data.map((post) => {
            return '/posts/' + post.id
          })
        })
    }
  },

デプロイ時から投稿が増えても、nuxt generateコマンドが実行されない限りルートは追加されません。

よって、ブログのようにルートが動的に増えるタイプのサービスには不向きなデプロイ方法となります。

Node.jsアプリとしてデプロイする

こちらの方法では、動的ルーティングにも対応することができます。

簡単なデプロイ方法としてはHerokuGoogle App EngineといったNode.jsを使用できるPaaSにデプロイする方法が挙げられます。

Herokuにデプロイ

Herokuにサインアップ後、Heroku CLIをインストールして、以下を実行します。

$ cd /path/to/workspace
$ heroku login
$ heroku git:remote -a <Project Name>

ここまできたら続きはNuxt公式がまとめてくれています。

Heroku へデプロイするには? - NuxtJS

Google App Engineにデプロイ(2020/01/18追記)

1. デプロイのための設定ファイルを設置

プロジェクトのリポジトリのルートにapp.yamlを設置します。

runtime: nodejs10

instance_class: F2

handlers:
  - url: /_nuxt
    static_dir: .nuxt/dist/client
    secure: always

  - url: /(.*\.(gif|png|jpg|ico|txt))$
    static_files: static/\1
    upload: static/.*\.(gif|png|jpg|ico|txt)$
    secure: always

  - url: /.*
    script: auto
    secure: always

env_variables:
  HOST: '0.0.0.0'
  NODE_ENV: 'production'

handlersyarn buildにより生成されたファイルをどのURLにマッピングするかを指定しています。

詳しい説明についてはGoogle App Engineのリファレンス(https://cloud.google.com/appengine/docs/standard/nodejs/config/appref?hl=ja)をご覧ください。

ざっくり説明すると、

  • /_nuxt.nuxt/dist/clientにマッピング
  • /.*\.(gif|png|jpg|ico|txt)$staticディレクトリ内の拡張子がgif|png|jpg|ico|txtのものにマッピング
  • すべてのURLはデプロイしたNuxtのアプリが処理する必要があることを指定

2. gcloudコマンドでデプロイ

GCPプロジェクトを作成とgcloudコマンドのインストールを完了させ、以下のコマンドを実行します。

gcloud app deploy app.yaml --project [project-id]

これらの手順はGoogle App Engine へデプロイするには? - NuxtJSにまとまっているので、そちらも合わせてご覧ください。

まとめ

  • 動的ルート無し => 静的ファイル生成後デプロイ
  • 動的ルート有り => Node.jsアプリとしてデプロイ

静的ファイルとしてデプロイできることの恩恵はでかいので、動的ルートはできるだけ使用しないでアプリを構築できると良いかもしれません。

*1:詳細はhttps://ja.nuxtjs.org/api/configuration-generate/#routesにて解説されています。