今回やったこと
- Nuxt3を利用したアプリケーション開発
- Serverless Frameworkを使ったAWSLambdaへのデプロイ
- PrimeVueを使ったUI作成
- 静的なリソースはLambdaには渡さずCloudFrontを経由してS3からファイルを返す
- masterへのプッシュをトリガーとした別リポジトリへのプッシュ(GitHub Actions)
作ったものについて
画面上部に操作ボタン、下に1行1冊のノウハウブック入力欄を表示しています | PrimeVueに含まれるテーマについて動的に切り替え可 |
ノウハウ1~20はモーダルウィンドウ内で入力できます | 入力内容はミニファイされたjsonファイルとしてダウンロードできます このjsonファイルからの復元も可 |
- ノウハウブックについてゲーム内で管理がし辛いのを改善する目的で作成
- とにかくNuxt3で開発をしてみたかった
- この記事を書いてる現在も作り途中。以下を後ほど積み込む予定
- 複写機能を作成
- ノウハウごとの取得情報を表示するビューを作成
- キャラクターごとノウハウごとの最大レベルを表示するビューを作成
以下にサンプルとして自分の手持ちのノウハウブックの何冊かを入力したjsonファイルを置いておきます。「復元」ボタンからインポートできると思います。
1 ファイル 0.24 KB
Nuxt3について
今回の開発を経て覚えたことなど
- VSCodeでの開発はVolarを入れとけば多分大丈夫
- nuxt.config.ts(もしくはNITRO_PRESET環境変数)のプリセット設定によって、各環境に合わせた専用のビルドが行える
- AWSのLambdaで動かすサーバーレスなアプリを公開したいのであればNITRO_PRESET=aws-lambda
- 単純にNode.jsで動かしたければNITRO_PRESET=node-server
- フレームワーク固有のディレクトリがある
- publicに置いたファイル(favicon.icoとか)はビルド時に.output/publicにコピーされる
- componentsに置いたSFCは、.nuxt/components.d.tsに自動で追加されエディタ内でコードの補間が行える
など
- 開発にDockerを使う場合、ホストPCと同期してるディレクトリでnpx nuxi create .からプロジェクトを作るのが良いかも。
- その後、ESLintとprettierインストール設定するとそのままフロントエンドの開発が行える
Serverless Frameworkについて
今回の開発を経て覚えたことなど
- serverless.ymlにデプロイに関する設定を記述
- resources:の中でCloudFormationのyml形式のテンプレートを直接書くこともできる模様
- npx serverless deployからデプロイ
- AWS上ではCloudFormationのスタック作成の処理が稼働しデプロイされている
- 当然だけどLambdaにデプロイするのであればIAMのクレデンシャルを設定しておく必要がある
- npx serverless config~~から設定可能
- ユーザーのホームディレクトリ以下に.aws/credentialsが出来上がるのでaws-cliが入ってるのであればaws configureからでも同じ設定が可能と思われる
- 開発環境にDockerを使うのでAWSのアクセスキーとシークレットキーは.envから渡してコンテナ起動後に以下のようなコマンドで設定した
docker-compose exec nuxt bash -c 'npx serverless config credentials --provider aws --key $$AWS_ACCESS_KEY_ID --secret $$AWS_SECRET_ACCESS_KEY'
- デプロイが成功するまでに新規で追加したポリシーは以下のような感じ
2023/02/18追記
“logs:DeleteLogGroup”、”logs:DeleteLogStream”ポリシーが不足していたことが原因でserverless removeのコマンドが正しく動作していませんでした。以下に記載のコードに追記しました。{ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": [ "logs:DeleteLogGroup", "s3:*", "cloudformation:DescribeStackResource", "cloudformation:CreateChangeSet", "logs:TagResource", "s3-object-lambda:*", "logs:CreateLogGroup", "logs:DeleteLogStream", "cloudformation:DeleteChangeSet", "cloudformation:DescribeStacks", "iam:*", "logs:CreateLogStream", "cloudformation:DescribeStackEvents", "cloudformation:GetTemplate", "cloudformation:DeleteStack", "lambda:*", "cloudformation:DescribeChangeSet", "cloudformation:ExecuteChangeSet", "cloudformation:ValidateTemplate", "cloudformation:ListStackResources" ], "Resource": "*" } ] }
- デプロイ実行時に必要なポリシーが不足してる場合に、必要なポリシーを通知してくれるものとしてくれないものがあった。。どれが必要なのかが分からず上のような感じでアスタリスク指定してしまっている。。
- デプロイ失敗時にCloudFormationのスタックが残り続けてしまうことも何度かあった。。
PrimeVueについて
- Nuxt3で使うのにせっかくなので何か使ったことの無いUIフレームワークを使ってみようと思い選んだのがこれ。
- おそらくVue3で使えるUIフレームワークの中ではかなり高機能な方。
- ドキュメント読んでよく分からないところは、GitHubのソース読んだりする必要はあった
- データをテーブル表示するDataTableコンポーネントは使うのが難しいけど、フィルタ機能とかうまく動くとかなり使い勝手の良いUIになる
- scss/sassは含まれていない
- 有料のデザイナーライセンスというのを取得する必要があるみたい? → How to use the SASS api? · Issue #438 · primefaces/primevue
- 今回は1ページのシンプルなアプリなので問題にならなかった
- 日本語環境(全角入力)で不具合なんじゃないかなと思う挙動を見つけた&修正できたので後でissueとPR送るかもしれない。
- フレックスコンテナ、グリッドレイアウトなどのレイアウト周りが別のOSS(primeflex)に分離されている。
- 試してないけどレイアウトの作成にbootstrap5、コンポーネントはprimevueみたいな使い方とかもできるかもしれない?
GitHubのリポジトリ構成
- shinycolors-step-knowhow-manager(プライベートなのでリンク無し)
- Nuxt3アプリケーション本体
- 勉強用に残したコメントが大量に残ってるのでリポジトリは非公開
- shinycolors-step-knowhow-manager-dist
- node-server向けのnuxt buildのビルドで生成されるファイル一式を格納するリポジトリ
- shinycolors-step-knowhow-managerのmasterへのプッシュをトリガーにnode-server向けのnuxt buildを行い、成果物をdistリポジトリにプッシュするというGitHub ActionsのCDを組んだ
- shinycolors-step-knowhow-manager-docker
- Dockerを使ってshinycolors-step-knowhow-manager-distの動作環境を構築するリポジトリ
- Nodeのコンテナを立てる→distリポジトリをクローンする→node-server用のindex.mjsを実行しているだけ
- アプリケーションのソースをホストPC側に残したくないのでサブモジュールではなくクローンする方針としてみた
GitHub Actionsについて
↑のリポジトリ構成にも書いたGitHub Actionsを使ったCDについて以下のような定義になりました。
name: Deploy on: push: branches: - master jobs: deploy: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v3 with: path: main - name: Build with Node.js uses: actions/setup-node@v3 with: node-version: 18 - name: Package install and Nuxt build working-directory: main/front run: | npm install npm run build-for-publish - name: Checkout publish repo uses: actions/checkout@v3 with: repository: imo-tikuwa/shinycolors-step-knowhow-manager-dist path: publish token: ${{ secrets.GH_ACCESS_TOKEN }} - name: Copy built src run: | rm -fR publish/public/ rm -fR publish/server/ cp -r main/front/.output/* publish/ - name: Setup git repogitories run: | git config --global user.email "${{ github.event.pusher.email }}" git config --global user.name "${{ github.event.pusher.name }}" - name: Push publish repo working-directory: publish run: | git add -A git commit -m "Build and Deploy" git push origin master
{ "private": true, "scripts": { "build": "NITRO_PRESET=aws-lambda nuxt build", "build-for-publish": "NITRO_PRESET=node-server nuxt build", 省略 }, "devDependencies": { 省略 } }
概ね以下のようなことをやっています。
- mainという名前でshinycolors-step-knowhow-managerリポジトリをクローン
- publishという名前でshinycolors-step-knowhow-manager-distリポジトリをクローン
- ${{ secrets.GH_ACCESS_TOKEN }}で参照してるシークレットは読み取りと書き込みの権限が付いているアクセスキー
- Node.js18の環境を用意し、npm installとnode-server用のnuxt buildを実行
- nuxt buildによって生成された.outputディレクトリのファイル一式をdistリポジトリにコピー
- GitHubのユーザー設定としてトリガー元のGitHubユーザーとメールを設定
- 変更差分を全部ステージしてコミット、プッシュ
↑run内で実行するコマンドについて、先頭でpwdやls -alなどを実行しておくと、ディレクトリが間違ってないか、意図した生成が行えているかなどを確認できる。
CloudFrontについて
※実際には参考サイトのCloudFormationのテンプレートを使用して構築しました。
以下のようなオリジンを登録。
以下のようなビヘイビアを登録。
以下はnuxt-static-resourcesで設定したS3
- 優先順位0~2の設定に一致するリクエストは、nuxt-static-resourcesというオリジンで設定されている静的なリソースを含むS3を参照する。
- /_nuxt/*、/favicon.ico、/themes/*以外はLambdaに渡る
- 今回のアプリは1ページだけのアプリなので/(インデックス)のリクエストがLambdaに渡る
- 以下は上記の設定をした状態で動作確認したときの開発者ツールのキャプチャ
- /_nuxt配下の静的なリソースがCloudFrontを経由してCloudFrontから返されたことを確認したもの。応答ヘッダー内のx-cacheでHit from cloudfrontという文字が確認できる。
まとめた構成図
今回の一連のアプリケーション開発を全てまとめた構成図は以下のような感じ(だと思っている)。
感想
- Docker使って構築するコンテナがNode.jsだけなのでいつもより環境構築で考えることが少なかった気がした
- Nuxt3はstable版がリリースされてからまだ日が浅いので始めどきと言えるかも?
- Nuxtに限った話じゃないけど以前のバージョンと情報が混在するのが少しだけ辛い。。
- 仕事では主にバックエンドにPHPのLaravelを使ってるのでlaravel-vite-pluginやlaravel-mixを使用して、リポジトリ内にバックエンドとフロントエンドのコードが混在するようなアプリケーション開発を行ってるので、バックエンドを持たない(サーバーレス)アプリケーションは新鮮
- 仕事でもバックエンドとフロントエンドでリポジトリ自体を分離できたりするとデプロイの幅が広がるかも?
参考サイト
- Nuxt3入門(第9回) – Nuxt3アプリケーションをサーバーレス環境にデプロイする | 豆蔵デベロッパーサイト
- Nuxt3で作ったアプリをLambdaにデプロイするために必要となる手順がまとまっている。すごく読みやすい。
- CloudFrontをCloudFormationから構築するテンプレートについても参考にさせていただきました。
- 📝 Nuxt 3 公式ドキュメント 日本語訳
- 長いので上から下まで全て読んだわけではないけど、ググってヒットしたときに該当箇所について勉強させていただきました。
- nuxt3でprimevueを使う | デバッグライフ
- Nuxt3にPrimeVueを導入するにあたってのプラグイン設定について参考にさせていただきました。
- GitHub Actions で別のリポジトリに git push する
- 今回実現したかったことと全く同じ内容のため、色々参考にさせていただきました。
- push先のリポジトリをクローンする処理の中でGH_ACCESS_TOKENという名前でアクセスキーを参照していたからか、私のケースではデプロイキーの設定は不要でした(NeverUsedのまま使われなかった)。
よくよくみたらDeployKeysがNeverUsedのままだったので、外して再度CD動かしてみたら必要な権限が設定されてるアクセスキーだけでもちゃんと動いた😤 pic.twitter.com/b4QJdWe5YL
— ぼこちょ (@imo_tikuwa) February 7, 2023