Vue3 + Express + MySQLで携帯図書館フルスタックアプリを作ってみた、およびエラー解決の記録
はじめに
はじめまして、今回がQiitaへの初投稿となります。
現在、フルスタックなWebアプリケーションの開発に挑戦しています
尚、この開発は業務などとは関係なく個人的な開発です。
この開発はAIのサポートを受けながら、技術について教わりつつコードを書いています。
右も左も分からない状態からスタートしましたが、
一歩ずつ仕組みを理解しながら進める開発は非常に楽しく、
充実した時間を過ごしています。
この記事が、私と同じようにゼロから
フルスタック開発に挑戦している初学者の方の助けになれば嬉しいです。
また、まだまだ勉強中の身ですので、
経験者の方からの
「もっとこうした方が良い」「ここにはこういう罠がある」
といったご指摘やフィードバックもぜひいただきたいと考えております。
どうぞよろしくお願いいたします。
1. 全体のアーキテクチャと役割
本アプリは、以下の3つのレイヤーが連携して動くWebアプリケーションです。
- フロントエンド (Vue 3 / TypeScript / Vite): 画面の表示、ユーザーの入力受け取りを担当。
- バックエンド (Express / TypeScript): データベースとの通信を中継する「Web API」を提供。
- データベース (MySQL): データの永続化(保存)を担当。
2. 開発のステップ
Step 1: フロントエンドのセットアップ
Vue 3 + TypeScript(Viteベース)の環境を用意し、まずは画面(UI)を作成しました。
この時点では、データはメモリ上の仮データ(モックデータ)を使用して動作を確認しています。
Step 2: バックエンドのセットアップとMySQL接続
Expressサーバーを立ち上げ、mysql2 パッケージを使ってローカル環境のMySQLと接続する基盤を作成しました。
Step 3: APIの実装とフロント・バックの結合
フロントエンドからバックエンドへデータをリクエストするため、通信ライブラリの axios を導入しました。Expressが提供する「Web API」を叩いて、データを送受信する処理を実装しています。
3. 実際に直面したエラーと解決プロセス
開発中に発生した以下のエラーは、どれもフルスタック開発の構造を理解する上で非常に勉強になったポイントです。
エラー①:Error: Cannot find module 'express' (MODULE_NOT_FOUND)
-
状況:
npm run devでバックエンドを起動した際に発生。 -
原因:
backendフォルダではなく、上の階層などでnpm installを実行していたため、プロジェクト内にパッケージが存在しなかった。 -
解決策: 正しいディレクトリ(
backend/)に移動し、改めてnpm install expressを実行。package.jsonのdependenciesに正しく追加されたことを確認して解決。
エラー②:ER_ACCESS_DENIED_ERROR (errno: 1045)
- 状況: バックエンドは起動したものの、MySQLへの接続時に発生。
-
原因: 接続情報(
user,password)が初期サンプルのままで、自身の環境のMySQLのパスワードと一致していなかったため、認証を拒否された。 -
解決策:
src/index.tsのデータベース接続設定を、自身の本物のパスワードに書き換えることで接続成功。
エラー③:ER_NO_REFERENCED_ROW_2 (errno: 1452)
-
状況: 画面から新しい本を登録(
INSERT)しようとした際に発生。 -
原因: データベースの「外部キー制約(Foreign Key Constraint)」によるエラー。
booksテーブルにuserid = 1で登録しようとしたが、大元のusersテーブルにまだid = 1のユーザーが存在しなかったため、MySQLがデータの矛盾を防ぐためにガードした。 -
解決策: MySQL側で、あらかじめ親データとなるユーザーを直接挿入。
※この際、
INSERT INTO users (id, name, password) VALUES (1, 'yuya', 'password123');passwordカラムが必須(NOT NULL)かつデフォルト値なしに設定されていたため、Field 'password' doesn't have a default valueエラーも同時に発生しました。しっかりパスワードも含めてインサートすることで解消しています。
4. 今回の学び・Vue.jsの便利機能
実装の中で、Vue.jsが持つ強力な標準機能(修飾子など)の便利さを実感しました。
-
@submit.prevent="addBook"
通常のHTMLフォームが持つ「送信時にページ全体をリロードする」という標準動作を、.preventを添えるだけで裏で自動キャンセルしてくれる機能。シングルページアプリケーション(SPA)に必須の仕組みだと学びました。 -
v-model.number="newBookVolume"
HTMLの入力フォームは数字を入れても裏では「文字列」として扱われてしまう性質があります。.numberをつけることで、Vueが自動的にJavaScriptの「数値型(number型)」に変換してくれるため、計算バグやDBの型エラーを防ぐことができます。
5. 今後の課題(ディレクトリの適切な分離)
今回は1つのファイルに処理をまとめて記述しましたが、規模が大きくなるにつれてコードが肥大化するため、以下のようなディレクトリ分割(設計パターン)にリファクタリングしていくことが推奨されると学びました。
-
フロントエンド: 画面(
views/)と、部品(components/)に分け、ルーター(router/)で切り替える。 -
バックエンド: 窓口(
routes/)、頭脳(controllers/)、DB操作(models/)の3つに役割を綺麗に分離する(MVCアーキテクチャの思想)。
おわりに
画面、サーバー、データベースが1つの線で繋がった瞬間は非常に感動しました。
エラーが起きるたびにログを読み解き、
どこに原因(パッケージか、認証か、DBの制約か)があるかを切り分ける
デバッグの重要性を深く学べる良い開発体験となりました。
これからも開発を楽しみながら、さらに知識を深めていきます。
さらに今回は文字ベースになってしまいましたが、
次回以降は実際のコードも記載して投稿していきたいと思います
最後まで読んでいただき、ありがとうございました。