avatar

Monorepo 專案架構

前言

我的個人專案採用monorepo架構,最一開始的版本我採用前端、後端各有repo的架構但是後來發現這樣在開發上會延伸出以下幾點問題

  • 啟動專案的時候我會需要開至少兩個terminal分別執行前端、後端的dev指令。
  • 在實作中常常遇到前端、後端都會使用到的class、entity、function...等等,這導致我會需要分別在專案中都實作。 其中這點是讓我最不能接受的,我在寫程式的時候一直想盡量保持DRY(Don't Repeat Youself)。(算是一種強迫症)
  • 在git commit的部分不好的一次做管理,假設後端新增了一個api而前端需要做相對應的改動相關的commit紀錄就會在不同的repo會造成追蹤的困難

專案架構圖

  • web
    • backend (ExpressJs)
    • frontend (NextJs)
    • common (這裡主要是放typeorm entity)

Monorepo的實現

目前有Lerna、Nx這種工具可以輕鬆的管理monorepo架構的關聯,我在建置初期有嘗試使用過Nx,最後是選擇放棄了主要原因是心智負擔太大,殺雞焉用牛刀, 我覺得我光是要搞懂Nx即便在有LLM的幫助下也會非常的花費時間,而此外我也想要了解如果不使用Nx這類工具應該要如何實現monorepo。

實作

根據上方的專案架構圖,我們來實際操作一次,因為主要的目的是monorepo因此frontend的資料夾就不創建成一個NextJs專案簡單的看成普通專案即可。

//首先建立一個主資料夾 mkdir web // 進入主資料夾後進行npm初始化 cd web npm init // 創建應用資料夾 mkdir frontend mkdir backend mkdir common // 分別進入應用資料夾進行npm init cd frontend && npm init cd backend && npm init cd common && npm init

接著就是比較重要的部分需要修改主資料夾以及應用資料夾的package.json來達到monorepo

  • 首先需要在web下安裝npm套件concurrently, concurrently可以讓你同時執行多個 npm 腳本或命令。
cd web npm i concurrently
  • 修改web下的package.json,新增scripts中的dev命令以及workspaces
{ "name": "web", "workspaces": ["backend", "frontend", "common"], "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "dev": "concurrently \"npm run dev --workspace=backend\" \"npm run dev --workspace=frontend\"", }, "author": "", "license": "ISC" }

這行命令主要是同時執行frontend、backend、common這三個workspace下的dev指令,以NextJs來說的話dev指令會是next dev用來運行NextJs開發環境 透過該指令我在開發的時候運行開發環境只需要在web資料夾下輸入npm run dev即可。

concurrently \"npm run dev --workspace=backend\" \"npm run dev --workspace=common\" \"npm run dev --workspace=frontend\"
  • 分別確認frontend、backend、common下的package.json下的name屬性是否為web下對應的workspaces,以frontend為例子,name應該要是frontend這樣在 web下運行的npm指令才會認得frontend這個workspace
{ "name": "frontend", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC" }
Monorepo 專案架構 | SIC 個人網站