N-LAB

Nuxt.jsのSPAモードでAmazon S3にデプロイする方法


目標

※本手順書ではNuxtのプロジェクトの作成に関しては省略しています。

前提


目次

  1. バケットの作成
  2. プロジェクトのアップロード
  3. 静的ウェブサイトホスティング機能の有効化
  4. アクセス許可の設定
  5. APIを利用する場合の注意点


バケットの作成

AWSにログイン後にサービスよりS3を選択し、バケットを作成を押下します。
バケット一覧
バケット名に任意の一意な名前を設定します。
※本手順書では「nuxt-spa-amazon-s3」と設定しています。
AWS リージョンは「アジアパシフィック(東京)」を選択します。
バケット名入力
「パブリックアクセスをすべてブロック」のチェックを外します。
「現在の設定により、このバケットとバケット内のオブジェクトが公開される可能性があることを承認します」にチェックをつけます。
アクセス権限設定
バケットを作成を押下します。
バケット作成
作成したバケットが一覧に表示されます。
バケット作成完了

プロジェクトのアップロード

ローカルに作成済みのNuxtプロジェクトを以下のコマンドでビルドします。

npm run generate

ビルド後にプロジェクトのルートディレクトリに「dist」ディレクトリが作成されます。
「dist」ディレクトリの中身は以下の構造になっています。

dist
  ├───_nuxt
  ├───hoge/index.html ← pages配下にあるvueファイルがhtmlに変換※1
  ├───200.html        ← エラーページ
  └───favicon.ico

※1 「dist」ディレクトリに生成されるディレクトリ名はpages配下に存在するvueファイル名と同じになります。
エラーページはデフォルトでファイル名が「200.html」で生成されます。
ファイル名を変更するにはnuxt.config.jsに以下を追記します。

export default {
 ...
  generate: {
    fallback: 'error.html'
  }
 ...
}

上記の場合、ビルド時にファイル名が「200.html」ではなく「error.html」で生成されます。
ビルドしてできたファイル類をS3にアップロードするには以下の手順を実施します。
手順「バケットの作成」で作成したバケットの名前を押下します。
バケット選択
アップロードを押下します。
アップロード
「dist」ディレクトリの中身すべてをこの画面にドラッグアンドドロップします。
ドラッグアンドドロップ
アップロードを押下します。
アップロード中
アップロード完了後は以下の画面が表示されます。
アップロード完了

静的ウェブサイトホスティング機能の有効化

手順「プロジェクトのアップロード」でアップロードしたファイルがS3から公開されるために、S3の静的ウェブサイトホスティング機能を有効にします。
手順「バケットの作成」で作成したバケットの名前を押下します。
バケット選択
プロパティを選択し、静的ウェブサイトホスティングの編集を押下します。
静的ウェブサイトホスティング
「静的ウェブサイトホスティング」の「有効にする」を選択します。
静的ウェブサイトホスティングの有効化
「インデックスドキュメント」にトップページのファイル名を入力します。
「エラードキュメント – オプション」にエラーページのファイル名を入力します。
※ここで入力するファイル名は、手順「プロジェクトのアップロード」で生成された「dist」ディレクトリ内の任意のhtmlのファイル名を入力します。
変更の保存を押下します。
ページ設定
完了後は以下の画面が表示されます。
静的ウェブサイトホスティング有効化完了

アクセス許可の設定

手順「バケットの作成」で作成したバケットの名前を押下します。
バケット選択
アクセス許可を選択し、バケットポリシーの編集を押下します。
アクセス許可
ポリシー欄に以下を入力します。
※「”Resource”: “[バケットARN]/*”」の[バケットARN]はポリシー欄の上部に表示されているバケットARNを入力します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "[バケットARN]/*"
        }
    ]
}

変更の保存を押下します。
バケットARN
アクセス許可の概要欄のアクセスが「公開」になっていれば、手順「プロジェクトのアップロード」でアップロードしたファイルがS3から正常に公開されている状態になっています。
公開
公開したページへアクセスするには、プロパティを選択し、バケットウェブサイトエンドポイントに記載のURLを押下します。
ページアクセス
以上で全ての手順は完了になります。
以降ではNuxtをSPAモードでapiを利用する場合の注意点について解説します。

APIを利用する場合の注意点

SPAモードで作成したNuxtプロジェクトでaxios等で外部のAPIへリクエストを行う場合に以下の問題が発生します。
nuxt.config.jsに以下のようにproxyの設定をしていてもproxyが動作しません。

export default {
 ...
  proxy: {
    '/api/': {
      target: 'http://hogehoge.com',
    },
  },
 ...
}

SPAモードではproxyは動作しないのでaxiosのbaseURLを利用します。

export default {
 ...
  axios: {
    baseURL: "http://hogehoge.com",
  },
 ...
}


S3にデプロイしたNuxtアプリからローカルで起動したサーバーのAPIへリクエストを送信してもブロックされる場合があります。
これはChromeのセキュリティ強化によりHTTP通信でローカルIPアドレスへのリクエストがブロックされるようになったためです。
リクエストを許可するにはアドレスバーに以下を入力してEnterキーを押下します。

chrome://flags/

以下の項目をDisabledに設定してブラウザを再起動します。

Block insecure private network requests.

再起動後は、S3にデプロイしたNuxtアプリからローカルサーバーのAPIへ正常にリクエストが送信されます。
※Chromeに限らず、Microsoft Edgeでも同様の対応で本事象を解消可能です。