Monorepo 架構設計 npm workspaces Prisma MVP

Monorepo 全端專案從 0 到 1 拆解紀錄

EZ Tech 編輯部

專案背景

這是一個包含 Astro 前端、Express API、Python FastAPI 與 Nginx 反向代理的全端系統。從一開始就選擇了 Monorepo 結構,讓所有服務的依賴、腳本與環境變數能集中管理。

Monorepo 結構設計

my-project/
  apps/
    web/          # Astro 5 前端
    api/          # Express + Prisma
    python-service/  # FastAPI
  packages/
    database/     # Prisma schema 共享
  infra/
    nginx/        # Nginx 設定
  package.json    # 根 workspace
  docker-compose.dev.yml

為什麼不用 Turborepo?

評估後決定直接用 npm workspaces,原因:

  1. 依賴數量不到需要 Turbo 的程度
  2. CI 只有一個主管道,不需要 task graph caching
  3. 減少工具鏈複雜度是 MVP 階段的優先事項

路由約定

所有服務統一由 Nginx 代理:

路徑前綴服務Port
/Astro 前端4321
/api/*Express API3001
/py/*Python FastAPI8000

這個約定一旦確定就不能輕易改動,因為前端所有 API 呼叫都依賴這個路由契約。

Prisma 跨服務共享

packages/database 放置主要 Prisma schema,讓 Express API 使用:

// packages/database/package.json
{
  "name": "@ez/database",
  "scripts": {
    "generate": "prisma generate",
    "push": "prisma db push"
  }
}

根層的 npm scripts 用 dotenv-cli 確保 .env 被正確載入:

"prisma:generate": "dotenv -e .env -- npm -w packages/database run generate"

最大踩坑:環境變數作用域

問題:在各子 app 目錄下直接跑 prisma db push,DATABASE_URL 會找不到。

根因.env 放在根目錄,子 app 的 Prisma CLI 預設找的是自己目錄下的 .env

解法:所有 Prisma 操作只從根目錄的 npm scripts 執行,並用 dotenv-cli 顯式載入根 .env

架構決策記錄 (ADR)

ADR-001: 選擇 Nginx 作為反向代理而非在 Express 中 host Astro

原因:開發/生產環境行為一致,Nginx 的 SSE proxy buffering 設定也更直觀。

結語

MVP 階段的架構重點是「容易理解」重於「完美擴展性」。這套 Monorepo 設計讓一個人可以同時掌握前後端、部署與資料庫,是小團隊快速迭代的好起點。

準備好開始你的專案了嗎?

讓我們一起規劃最適合的數位解決方案,從需求訪談到上線部署,全程陪伴。

Start a Project →