使用 Turborepo 的 Remix Gospel Stack

The Remix Gospel Stack

使用 Turborepo 管線、Prisma、PostgreSQL 或 SQLite (Litefs)、Docker 部署到 Fly.io、pnpm、shadcn/ui TailwindCSS 的 Remix TypeScript monorepo。

pnpm create remix@latest --init-script --install --template https://github.com/PhilDL/remix-gospel-stack

:minidisc: 此儲存庫是有偏好的

  • 僅限 TypeScript
  • 僅與 pnpm 套件管理器相容,用於處理 monorepo 工作區。
  • 使用 turborepo 管線 + 快取來建置、檢查程式碼風格、類型檢查和測試 monorepo。

(替代方案)複製儲存庫

git clone git@github.com:PhilDL/remix-gospel-stack.git
cd remix-gospel-stack
pnpm add -w @remix-run/dev
pnpm remix init

堆疊中的內容

此堆疊是一個以 Remix 為導向的 Monorepo,由 turborepo 和 pnpm 工作區提供支援。包含一個可透過建置 Docker 容器部署在 fly.io 上的 Remix 應用程式。

此套件使用 pnpm 作為套件管理器來管理工作區。如果將工作區定義放在 package.json 檔案中,則可以使用 yarnnpm,但不保證可以正常運作。

Turborepo 和 pnpm 工作區提供支援的 Monorepo 架構

  • 包含應用程式的 apps 資料夾

  • 包含範例的 packages 資料夾

    • ui:由 shadcn/ui 提供支援的 React UI 套件範例。一些範例元件和作為 Tailwind 外掛程式和預設值匯出的 shadcn/ui Tailwind 設定。
    • databasePrisma 包裝函式,可直接在其他套件或應用程式中使用。與 tsup 捆綁。取決於您在安裝期間選擇的選項,可以是 PostgreSQL 或 SQLite // Litefs。
    • business:一個使用 Prisma database 作為相依性並使用*儲存庫模式*的範例套件。
    • internal-nobuild:一個純 TypeScript 範例套件,沒有建置步驟。套件的 main 進入點直接是 src/index.ts。Remix 會使用自己的建置步驟 (使用 esbuild) 來處理編譯。此套件也包含使用 Vitest 的單元測試。Remix 使用 tsconfig.json 路徑來參考該專案及其類型。當您不打算發布該套件時,我會建議使用這些類型的 internal 套件。
  • config-packages:

    • 具有不同預設設定的 Eslint 套件。
    • TS Configs,也具有不同的預設設定。
    • Tailwind 設定。

所有 Remix 未來旗標已啟用

future: {
  unstable_optimizeDeps: true,
  v3_fetcherPersist: true,
  v3_lazyRouteDiscovery: true,
  v3_relativeSplatPath: true,
  v3_throwAbortReason: true,
  v3_singleFetch: true,
  v3_routeConfig: true,
},

還有什麼?

警告 以下所有命令都應從 monorepo 根目錄啟動

開發

  • 安裝相依性。

    pnpm install
    

    您也必須複製範例 .env.example

    cp .env.example .env
    cp .env.example .env.docker
    
  • 啟動 postgresql docker 容器

    pnpm run docker:db
    

    注意:npm 指令碼會在 Docker 在背景設定容器時完成。請確保 Docker 已完成並且您的容器正在執行,然後再繼續。

  • 產生 prisma 結構描述

    pnpm run generate
    
  • 將 Prisma 遷移執行到資料庫

    pnpm run db:migrate:deploy
    
  • 執行第一次建置(透過 ... 選項使用相依性)

    pnpm run build --filter=@remix-gospel-stack/remix-app...
    

    單純執行 pnpm run build 將會建置所有內容,包括 NextJS 應用程式。

  • 執行 Remix 開發伺服器

    pnpm run dev --filter=@remix-gospel-stack/remix-app
    

在 PostgreSQL 和 SQLite (Litefs) 之間切換

  • 若要在 PostgreSQL 和 SQLite (Litefs) 之間切換,可以使用儲存庫根目錄中的 turbo 產生器。

    pnpm turbo gen scaffold-database
    

    然後依照提示操作。不過請注意,prisma 遷移連結到特定資料庫,因此您必須刪除 migrations 資料夾。

    注意:切換到需要另一個套件 (litefs-js) 的 SQLite (Litefs) 後,您必須再次執行 pnpm i --fix-lockfile。您可能也必須再次執行 pnpm run setup 以產生第一次遷移。

建立套件

內部套件

turbo gen workspace --name @remix-gospel-stack/foobarbaz --type package --copy

然後依照提示操作

測試、類型檢查、程式碼風格檢查、安裝套件...

檢查 turbo.json 檔案以查看可用的管線。

  • 執行 Cypress 測試和 Dev
    pnpm run test:e2e:dev --filter=@remix-gospel-stack/remix-app
    
  • 檢查所有程式碼風格
    pnpm run lint
    
  • 類型檢查整個 monorepo
    pnpm run typecheck
    
  • 測試整個 monorepo
    pnpm run test
    or
    pnpm run test:dev
    
  • 如何在 Remix 應用程式中安裝 npm 套件?
    pnpm add dayjs --filter @remix-gospel-stack/remix-app
    
  • 調整 config-package 資料夾中的 tsconfig、eslint 設定。任何套件或應用程式都將擴展這些設定。

在 fly.io 上部署 – PostgreSQL

警告 以下所有命令都應從 monorepo 根目錄啟動

在您第一次部署之前,您需要做一些事情

  • 首先註冊 fly CLI

    fly auth signup
    
  • 在 Fly 上建立兩個應用程式,一個用於預備,另一個用於生產

    fly apps create remix-gospel-stack
    fly apps create remix-gospel-stack-staging
    

    注意:成功建立應用程式後,請仔細檢查 fly.toml 檔案,確保 app 金鑰是您建立的生產應用程式的名稱。此 Stack 會在初始化時自動附加唯一後綴,這可能與您在 Fly 上建立的應用程式不符。如果您的應用程式名稱不符,您可能會在 Github Actions CI 日誌中看到 404 錯誤

  • 初始化 Git。

    git init
    
  • 建立新的 GitHub 儲存庫,然後將其新增為專案的遠端。請勿推送您的應用程式!

    git remote add origin <ORIGIN_URL>
    
  • FLY_API_TOKEN 新增至您的 GitHub 儲存庫。若要執行此作業,請前往 Fly 上的使用者設定,並建立新的 權杖,然後使用名稱 FLY_API_TOKEN 將其新增至 您的儲存庫密碼

  • 為您的預備和生產環境建立資料庫

資料庫建立

fly postgres create --name remix-gospel-stack-db
fly postgres attach --app remix-gospel-stack remix-gospel-stack-db

fly postgres create --name remix-gospel-stack-staging-db
fly postgres attach --app remix-gospel-stack-staging remix-gospel-stack-staging-db

注意:在連結預備資料庫時,您會收到與上述 fly set secret 步驟中相同的警告,原因相同。不用擔心。繼續!

Fly 會負責為您設定 DATABASE_URL 密碼。

在 fly.io 上部署 – SQLite Litefs

警告 以下所有命令都應從 monorepo 根目錄啟動

在您第一次部署之前,您需要做一些事情

  • 首先註冊 fly CLI

    fly auth signup
    
  • 在 Fly 上建立兩個應用程式,一個用於預備,另一個用於生產

    fly apps create remix-gospel-stack
    fly apps create remix-gospel-stack-staging
    

    注意:成功建立應用程式後,請仔細檢查 fly.toml 檔案,確保 app 金鑰是您建立的生產應用程式的名稱。此 Stack 會在初始化時自動附加唯一後綴,這可能與您在 Fly 上建立的應用程式不符。如果您的應用程式名稱不符,您可能會在 Github Actions CI 日誌中看到 404 錯誤

  • 初始化 Git。

    git init
    
  • 建立新的 GitHub 儲存庫,然後將其新增為專案的遠端。請勿推送您的應用程式!

    git remote add origin <ORIGIN_URL>
    
  • FLY_API_TOKEN 新增至您的 GitHub 儲存庫。若要執行此作業,請前往 Fly 上的使用者設定,並建立新的 權杖,然後使用名稱 FLY_API_TOKEN 將其新增至 您的儲存庫密碼

為預備和生產環境的 sqlite 資料庫建立永久磁碟區。執行下列命令(您可以根據您的需求和所選區域 (https://fly.io/docs/reference/regions/) 變更 GB 大小)。如果您變更區域,請確保您也變更 fly.toml 中的 primary_region)

fly volumes create data --region cdg --size 1 --app remix-gospel-stack
fly volumes create data --region cdg --size 1 --app remix-gospel-stack-staging

然後將磁碟區連結到應用程式

fly consul attach --app remix-gospel-stack
fly consul attach --app remix-gospel-stack-staging

開始編碼!

現在一切都已設定完成,您可以將變更提交並推送至您的儲存庫。每次提交到您的 main 分支都會觸發部署到您的生產環境,而每次提交到您的 dev 分支都會觸發部署到您的預備環境。

如果您在部署到 Fly 時遇到任何問題,請確保您已遵循上述所有步驟,如果已遵循,則將盡可能多的部署詳細資訊(包括您的應用程式名稱)發佈到 Fly 支援社群。他們通常會很快回應,希望能協助解決您的任何部署問題和疑問。

多區域部署

在單一區域中執行網站和資料庫後,您可以依照 Fly 的擴展多區域 PostgreSQL 文件新增更多區域。

請務必為您的應用程式設定 PRIMARY_REGION 環境變數。您可以在 fly.toml 中使用 [env] 設定,將其設定為您要用於應用程式和資料庫的主要區域。

在其他區域中測試您的應用程式

安裝 ModHeader 瀏覽器擴充功能(或類似的擴充功能),並使用它載入您的應用程式,並將標頭 fly-prefer-region 設定為您要測試的區域名稱。

您可以檢查回應中的 x-fly-region 標頭,以了解您的要求是由哪個區域處理的。

GitHub Actions

我們使用 GitHub Actions 進行持續整合和部署。任何進入 main 分支的變更,在經過測試/建置等流程後,都會部署到正式環境。任何在 dev 分支的變更,則會部署到預備環境。

手動建置 Docker 映像檔以使用 Fly.io 部署

  • 建立一個 Docker 網路
    docker network create app_network
    
  • 建置 Docker 映像檔
    pnpm docker:build:remix-app
    
  • 執行 Docker 映像檔
    pnpm docker:run:remix-app
    
  • (可選)如果你想手動部署到 fly.io
    DOCKER_DEFAULT_PLATFORM=linux/amd64 flyctl deploy --config ./apps/remix-app/fly.toml --dockerfile ./apps/remix-app/Dockerfile
    

了解更多關於 Turborepo 的強大功能

感謝

支持

如果你覺得此範本很有用,請考慮給它一個 星星 ⭐。謝謝!

免責聲明

我絕非 Monorepo、Docker 或 CI 方面的專家。這裡提出的設定只是眾多方法中的一種,可能可以改進 10 倍,但我自己也在不斷學習中,所以如果你發現任何可以改進的地方,請提交 PR。我將非常感謝!