LoginSignup
2
0

家族向け書籍管理アプリの開発①Vercelデプロイ

Last updated at Posted at 2023-12-14

センシンロボティクス Advent Calendar 2023 15日目の記事です。

はじめに

本アプリケーションは、家族間での書籍の重複購入を防ぐことを目的としています。開発は進行中で、現在の進捗は以下の通りです。

  • フロントエンド:開発環境を構築し、GoogleBooksApiを使用して書籍情報を取得し表示しています。
  • バックエンド:Loopbackを使用して各モジュールを作成し、Swaggerで動作を確認しています。

プロジェクトの概要

このアプリケーションは、家族全員の書籍を一元管理するためのものです。GoogleBooksAPIを使用して書籍情報を検索し、各書籍の紙媒体と電子媒体の所有状況、読了状況などを管理します。最終的な目標は、Flutterを使用してモバイルアプリケーションを作成し、バーコードスキャン機能を追加して書籍の登録を容易にすることです。

開発環境

開発には以下のツールが必要です。

  • Docker Desktop:アプリケーションの実行環境を構築します。
  • Visual Studio Code:コードの編集に使用します。
    • Remote Development(拡張機能):リモートの開発環境で作業を行うために使用します。

技術スタック

以下の技術を使用しています:

  • Docker: アプリケーションのコンテナ化
  • DevContainer: コンテナ内でのコーディング
  • TypeScript: 静的型付けとオブジェクト指向を提供
  • LoopBack: APIの作成と接続
  • Nuxt.js: Vue.jsのユニバーサルアプリケーションフレームワーク
  • Vue.js: UIの構築
  • Vuetify: Vue.jsのマテリアルデザインフレームワーク
  • Axios: PromiseベースのHTTPクライアント

内容

Vercelアカウントの作成と設定

Vercelはサーバーレスアーキテクチャを採用したクラウドプラットフォームです。以下の手順でアカウントを作成し、設定します。

  1. Vercelのサインアップページにアクセスしてアカウントを作成します。

  2. VercelのCLIツールをインストールします。

yarn global add vercel

# Vercel CLIでログインします。
vercel login

# アプリケーションをデプロイします。
vercel

# 本番環境へのデプロイは以下のコマンドを使用します。
vercel --prod

フォルダ構成

.
├── frontend
│   ├── node_modules
│   ├── nuxt.config.ts
│   ├── package.json
│   ├── tsconfig.json
│   ├── yarn.lock
│   ├── docker
│   │   └── Dockerfile
│   └── src
│       ├── assets
│       ├── components
│       ├── composables
│       ├── layouts
│       ├── pages
│       ├── plugins
│       └── utils
├── backend
│   └── docker
│       └── Dockerfile
├── docker-compose.yml
├── README.md
└── front
    ├── app.vue
    ├── node_modules
    ├── nuxt.config.ts
    ├── package.json
    ├── tsconfig.json
    └── yarn.lock

docker-compose.ymlを作る

version: '3.8'
services:
  frontend:
    build:
      context: ./frontend
      dockerfile: docker/Dockerfile
    volumes:
      - ./frontend:/app:cached
      - frontend_node_modules:/app/node_modules
    # - 構築時は下記コマンドをコメントにする
    # command: sh -c "yarn && yarn dev"
    ports:
      - 3000:3000
      - 24678:24678
    tty: true
    environment:
      - HOST=0.0.0.0
      - port=80
      - CHOKIDAR_USEPOLLING=true
  backend:
    build:
      context: ./backend
      dockerfile: docker/Dockerfile
    volumes:
      - ./backend:/app
      - backend_node_modules:/app/node_modules
    # - 構築時は下記コマンドをコメントにする
    # command: sh -c "yarn && yarn start"
    ports:
      - 3001:3001
    tty: true
    environment:
      - HOST=0.0.0.0
      - port=80
      - CHOKIDAR_USEPOLLING=true
  mysql:
    image: mysql:8.0
    command: --default-authentication-plugin=mysql_native_password
    environment:
      MYSQL_ROOT_PASSWORD: rootp@ssword
      MYSQL_DATABASE: "bookapp-db"
      MYSQL_USER: "bmuser"
      MYSQL_PASSWORD: "myp@ssword"
      MYSQLD_PUBLIC_KEY_RETRIEVAL: "true"
    ports:
      - 33306:3306
    volumes:
      - mysql-data:/var/lib/mysql
volumes:
  frontend_node_modules:
  backend_node_modules:
  mysql-data:

Dockerfileの作成と配置

以下の内容のDockerfileを作成します。これをfrontend/docker/Dockerfilebackend/docker/Dockerfileの両方に配置します。

FROM node:20-slim

WORKDIR /app

RUN apt-get update && apt-get install -y

Dockerコンテナの作成と起動

  • ターミナルを開き、以下のコマンドを実行してDockerコンテナを作成し、起動します。
docker compose up -d

フロントエンドの開発環境の構築

以下の手順でフロントエンドの開発環境を構築します。

  • Dockerコンテナに入ります。
docker compose exec frontend bash
  • Nuxt.jsのプロジェクトを作成します。
npx nuxi init . --force

このコマンドを実行すると、フロントエンドディレクトリに以下のファイルが作成されます。

.gitignore
.npmrc
app.vue
nuxt.config.ts
package.json
README.md
tsconfig.json
  • 必要なパッケージをインストールします。
yarn install

Nuxt.jsアプリケーションの起動と確認

以下の手順でNuxt.jsアプリケーションを起動し、正しく動作していることを確認します。

  • Nuxt.jsアプリケーションを起動します。
yarn dev
  • ブラウザでhttp://localhost:3000/にアクセスします。

「Welcome to Nuxt!」が表示されれば成功しています。

  • 確認が終わったら、ctrl + cを押してアプリケーションを停止します。

Vuetifyの導入と設定

VuetifyはVue.jsのマテリアルデザインフレームワークです。以下の手順で導入と設定を行います。

  • Vuetifyとその関連パッケージをインストールします。
yarn add -D vuetify vite-plugin-vuetify
yarn add @mdi/font
  • 必要なディレクトリを作成します。
mkdir -p src src/{assets,components,composables,layouts,pages,plugins,utils}
  • nuxt.config.tsを編集して、Vuetifyとsrcディレクトリの設定を行います。
import vuetify, { transformAssetUrls } from 'vite-plugin-vuetify'
export default defineNuxtConfig({
  srcDir: 'src/',
  build: {
    transpile: ['vuetify'],
  },
  modules: [
    (_options, nuxt) => {
      nuxt.hooks.hook('vite:extendConfig', (config) => {
        // @ts-expect-error
        config.plugins.push(vuetify({ autoImport: true }))
      })
    },
  ],
  vite: {
    vue: {
      template: {
        transformAssetUrls,
      },
    },
  },
})

この設定により、VuetifyがNuxt.jsアプリケーションで使用できるようになります。また、srcディレクトリがベースディレクトリとして設定されます。

  • src/plugins/vuetify.tsを作成します。このファイルではVuetifyの設定を行います。
import '@mdi/font/css/materialdesignicons.css'

import 'vuetify/styles'
import { createVuetify } from 'vuetify'

export default defineNuxtPlugin((app) => {
  const vuetify = createVuetify({
    // ... your configuration
  })
  app.vueApp.use(vuetify)
})
  • app.vueは使用しないので削除します。
  • src/layouts/default.vueを作成します。このファイルではアプリケーションの基本的なレイアウトを定義します。
<template>
  <v-app>
    <NuxtPage></NuxtPage>
  </v-app>
</template>
  • src/pages/index.vueを作成します。このファイルではホームページの内容を定義します。
<template>
  <div>
    <h1>Hello Vuetify3</h1>
    <v-btn color="primary" @click=handleClick>Hello</v-btn>
  </div>
</template>

<script setup lang="ts">
const handleClick = () => {
  alert("nuxt3");
}
</script>
  • ブラウザを開き、http://localhost:3000/にアクセスします。"Hello Vuetify3"と表示され、ボタンをクリックすると"nuxt3"というアラートが表示されれば、ホームページの作成に成功しています。

image.png

Google Books APIを使用して書籍情報を取得する方法

  • まず、HTTPリクエストを送信するためのライブラリであるAxiosをインストールします。
yarn add axios
  • 次に、src/pages/books.vueファイルを作成します。このファイルでは、Google Books APIを使用して書籍のタイトルを検索し、その結果をdatatableで表示します。
<template>
  <div>
    <v-text-field v-model="search" label="Search for books" @keyup.enter="fetchBooks" />
    <v-data-table :items="books">
      <template v-slot:item.thumbnail="{ item }" >
        <v-img 
          :src="item.thumbnail" 
          :aspect-ratop="16/9" 
          height="9vw" 
          min-height="100px"
          width="16vw" 
          min-width="160px" 
          class="ma-0 pa-0">
        </v-img>
      </template>
    </v-data-table>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import axios from 'axios'

interface Book {
  thumbnail: string
  title: string
  subtitle: string
  publishedDate: string
  description: string
}

const search: Ref<string> = ref('')
const books: Ref<Book[]> = ref([])

const fetchBooks = async () => {
  books.value = []
  const response = await axios.get(`https://www.googleapis.com/books/v1/volumes?q=${search.value}`)
  books.value = response.data.items.map((book: any) => {
    return {
      thumbnail: book.volumeInfo.imageLinks.smallThumbnail,
      title: book.volumeInfo.title,
      subtitle: book.volumeInfo.subtitle,
      publishedDate: book.volumeInfo.publishedDate,
      description: book.volumeInfo.description,
    }
  })
}
</script>
  • 機能の確認方法
  1. ブラウザを開き、http://localhost:3000/booksにアクセスします。

  2. 検索ボックスに検索したい書籍のタイトルや著者名を入力します。

  3. 入力後、Enterキーを押すと、検索結果が表示されます。

補足:この機能はGoogle Books APIを使用して書籍情報を取得し、その結果を表示します。検索ボックスに入力した文字列を含む書籍の情報が表示されます。

Vercelへのデプロイ方法

  1. まず、作成したプロジェクトをgitでcommitし、GitHubやGitLabなどのリモートリポジトリにpushします。
git init
git add .
git commit -m "First Commit."
git remote add origin https://github.com/{username}/{new_repo}.git
git push -u origin main
  1. 次に、ブラウザでVercelのサイトを開き、ログインします。

  2. "Add New"ボタンをクリックし、プロジェクトを選択します。

  3. GitHubと連携している場合、リポジトリ一覧が表示されるので、デプロイしたいリポジトリの"import"ボタンをクリックします。

  4. "Config Project"画面で、以下のように設定し、"Deploy"ボタンをクリックします。

Project Name: {任意の名前を設定}
Framework Preset: Nuxt.js
Root Directry: frontend  # Editボタンで選択可能
Build and OUtput Settings: デフォルトのまま
Enviroment Variables: デフォルトのまま
  1. "Congratulations!"と表示されれば、デプロイが完了です。"Continue to Dashboard"ボタンをクリックします。

  2. "Visit"ボタンをクリックし、デプロイしたページを開きます。

  3. アドレスバーでURLの末尾に/booksを追加し、ページを開きます。

image.png

git連携後は対象ブランチPUSH時にデプロイしてくれます。

次回への展望

今回はフロントエンドの開発についての説明を一旦終了します。次回は、この続きを予定しています。

補足:今回学んだ内容をしっかりと理解し、実践することで、次回の内容にもスムーズに取り組むことができます。次回もお楽しみに!

backendの開発環境を作る

  • コンテナに入ってloopback4の環境を作る
docker compose exec backend bash

# npm install -g @loopback/cli
yarn global add @loopback/cli

# LoopBack 4のプロジェクトを作成します。lb4 app コマンドを実行し、プロンプトに従ってプロジェクトの詳細を入力します。
lb4 app 

root@b2101ba89dc0:/app# lb4 app
? Project name: app
? Project description: Book Management Application
? Project root directory: app
? Application class name: AppApplication
? Select features to enable in the project Enable eslint, Enable prettier, Enable mocha, Enable loopbackBuild, Enable
vscode, Enable docker, Enable repositories, Enable services
? Yarn is available. Do you prefer to use it by default? Yes

  • 一階層無駄なのでフォルダの中身を移動(コンテナ内ではなくホスト側で実行)
# 'backend/app' ディレクトリの内容を 'backend/' ディレクトリに移動
mv backend/app/* backend/

# 空の 'backend/app' ディレクトリを削除
rmdir backend/app

次回への展望

バックエンドの開発についても時間切れのため一旦終了します。次回は、この続きを予定しています。
それとも久しぶりにGoで書いてみようかな

プロジェクトの課題点

このプロジェクトで直面した主な課題は以下の通りです:

  • Vercelを使用したデプロイ
  • DockerとDevcontainerを利用した、ホスト環境に影響を与えない開発環境の構築

結論

まだ全てを書き終えていませんが、少しずつ進めていきます。
VercelはGitHubなどとの連携設定だけで簡単にデプロイが可能でした。
VercelのTeam機能を使わずに、GitHub Actionsで直接デプロイする方法もあるようなので、試してみたいと思います。

参考資料

補足:Vercelは、フロントエンドのWebアプリケーションをデプロイするためのプラットフォームです。GitHubやGitLabなどのリモートリポジトリと連携して、簡単にデプロイを行うことができます。また、DockerとDevcontainerは、開発環境をコンテナ化し、ホスト環境に影響を与えずに開発を行うためのツールです。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0