♨️

Web サービスをフロントもバックも TypeScript で作る時の構成例

2024/07/15に公開

せっかくなのでフロントもバックも TypeScript を使おう、ということで、アレコレ考えて作った構成を共有します。何かの参考になれば幸いです。

下記の Web サービスを開発するときに使いました。
https://nc.harmonicom.jp/

システム構成

ランタイム:Bun
フレームワーク: Express
ORM:Drizzle ORM
インフラ:Docker

私的にはバックエンド中心で処理・出力し、そのうえでフロントエンドを使うのが好きです。

ディレクトリ・ファイル構成の例

あまり深くディレクトリを掘りたくなかったので、ルートに散在しています。

├── assets            :ビルドされたフロントエンドのファイルが入る
├── constants         :定数関係
│   └── index.ts
├── controllers       ;コントローラー
│   ├── _Controller.ts:ルート(/)のコントローラー
│   └── hogeController.ts
├── db                :データベース周りの初期設定やスクリプト
│   ├── index.ts      :DB接続スクリプト。各所から呼び出される
│   ├── migrate       :マイグレーションするSQLファイル
│   │   └── 0000_init.sql
│   └── migrate.ts    :マイグレーションスクリプト
├── drizzle           :Drizzle ORM が出力する定義類
├── frontend          :フロントエンドのソース
├── infra             :Dockerfileなどインフラ周りのファイル
├── libs              :ライブラリ類
│   └── index.ts
├── models            :モデル類
│   └── hogeModel.ts
├── public            :静的ファイル
├── routes            :ルーティングまわり
│   └── index.ts
├── types             :型ファイル
│   └── index.ts
├── views             :ビュー回り
├── .editorconfig
├── .env              :環境依存設定
├── .env.sample
├── .gitignore
├── .prettierignore
├── README.md
├── bun.lockb
├── compose.override.sample.yml
├── compose.yml
├── cron.txt
├── drizzle.config.ts
├── eslint.config.js
├── index.ts          :起動スクリプト
├── nodemon.json
├── package.json
├── postcss.config.js
├── prettier.config.js
├── tailwind.config.ts
├── tsconfig.json
└── vite.config.ts

実行時構成

  • docker compose で app サーバー・db サーバーを起動
  • app サーバー
    1. ディレクトリ自体を docker ボリュームとしてマウント
    2. bun install
    3. フロントエンドのビルド(Vite+Vue.js+Tailwind CSS)
    4. バックエンドの実行(nodemonでホットリロード対応)
      • Windows環境だとBunのホットリロードがうまく動かなかったため
    5. assets、public ディレクトリは静的ディレクトリとして利用
  • db サーバー
    • 初回起動時にスキーマを作成
    • app サーバーでマイグレーションやシーディングを行うことでDBが構築される
      • drizzle-kitのマイグレーションは使わずSQLを作成してマイグレーション

さいごに

昨今主流になりつつあるフロントとバックを切り離して開発する手法って、なんとなく工数が余分にかかる気がするんですよね。
API周りの仕様決めとか、相互の動作の調整とか、やり取りするデータの量とか、いろいろオーバーヘッドがあるような気がしています。
なので私は、昔ながらのバックエンドを中心としたつくりを好んでいます。

今回は構成だけでしたが、のちのちコードの解説とかもできればと思います。

Discussion