Remix Supa Fly Stack
此 Readme 將會盡快重新撰寫
深入了解 Remix Stacks。
npx create-remix --template rphlmr/supa-fly-stack
此 Stack 中包含什麼
- 使用 Docker 的 Fly 應用程式部署
- 可直接用於生產環境的 Supabase 資料庫
- 用於 Fly 備份區域回退的健康檢查端點
- GitHub Actions,用於在合併到生產和預備環境時進行部署
- 使用 基於 cookie 的會話的電子郵件/密碼驗證/魔法連結
- 使用 Prisma 的資料庫 ORM
- 使用 Remix Params Helper 的表單架構(用戶端和伺服器端!)驗證
- 使用 Tailwind 進行樣式設定
- 使用 Cypress 進行端對端測試
- 使用 MSW 模擬本機第三方請求
- 使用 Vitest 和 Testing Library 進行單元測試
- 使用 Prettier 格式化程式碼
- 使用 ESLint 進行程式碼檢查
- 使用 TypeScript 進行靜態類型檢查
不喜歡這個 Stack 的某些部分?Fork 它,更改它,然後使用 npx create-remix --template your/repo
!把它變成你自己的。
開發
-
建立一個 Supabase 資料庫(免費方案提供 2 個資料庫)
注意: 一個用於隨意使用 Supabase,或兩個用於
staging
和production
注意: 用完了所有免費方案? 也可搭配 Supabase CLI 和本機自行託管使用
注意: 建立一個強大的資料庫密碼,但最好使用密碼短語,這樣在連接字串中會更容易使用(無需逸出特殊字元)
例如:my_strong_passphrase
-
前往 https://app.supabase.io/project/{PROJECT}/settings/api 以尋找您的密鑰
-
「專案 API 金鑰」
-
在
.env
檔案中新增您的SUPABASE_URL
、SERVER_URL
、SUPABASE_SERVICE_ROLE
(又名service_role
secret
)、SUPABASE_ANON_PUBLIC
(又名anon
public
) 和DATABASE_URL
注意:
SERVER_URL
是您開發環境中的 localhost。它將適用於魔法連結登入
DATABASE_URL="postgres://postgres:{STAGING_POSTGRES_PASSWORD}@db.{STAGING_YOUR_INSTANCE_NAME}.supabase.co:5432/postgres"
SUPABASE_ANON_PUBLIC="{ANON_PUBLIC}"
SUPABASE_SERVICE_ROLE="{SERVICE_ROLE}"
SUPABASE_URL="https://{STAGING_YOUR_INSTANCE_NAME}.supabase.co"
SESSION_SECRET="super-duper-s3cret"
SERVER_URL="https://127.0.0.1:3000"
-
只有當您選擇不使用 CLI 為您安裝依賴項時,才需要執行此步驟
npx remix init
-
初始設定
npm run setup
-
啟動開發伺服器
npm run dev
這會在開發模式下啟動您的應用程式,並在檔案變更時重建資源。
資料庫種子腳本會建立一個新使用者,其中包含一些可供您開始使用的資料
- 電子郵件:
hello@supabase.com
- 密碼:
supabase
相關程式碼
這是一個相當簡單的筆記應用程式,但它很好地示範了如何使用 Prisma、Supabase 和 Remix 建構完整的堆疊應用程式。主要功能是建立使用者、登入和登出(處理存取和重新整理權杖 + 逾期時重新整理),以及建立和刪除筆記。
- auth / session ./app/modules/auth
- 建立和刪除筆記 ./app/modules/note
部署
如果您是 Fly.io 專家,請執行您所知道的操作。
此 Remix Stack 隨附兩個 GitHub Actions,可自動處理將您的應用程式部署到生產和預備環境。
在首次部署之前,您需要執行幾項操作
-
註冊並登入 Fly
fly auth signup
注意: 如果您有多個 Fly 帳戶,請確保您在 Fly CLI 中登入的帳戶與您在瀏覽器中登入的帳戶相同。在您的終端機中,執行
fly auth whoami
並確保電子郵件與登入瀏覽器的 Fly 帳戶相符。 -
在 Fly 上建立兩個應用程式,一個用於預備環境,一個用於生產環境
fly apps create supa-fly-stack-template fly apps create supa-fly-stack-template-staging # ** not mandatory if you don't want a staging environnement **
注意: 對於生產應用程式,請確保此名稱與您的
fly.toml
檔案中設定的app
相符。否則,您將無法部署。- 初始化 Git。
git init
-
建立新的 GitHub 儲存庫,然後將其新增為您專案的遠端。請勿立即推送您的應用程式!
git remote add origin <ORIGIN_URL>
-
將
FLY_API_TOKEN
新增至您的 GitHub 儲存庫。若要執行此操作,請前往 Fly 上的使用者設定並建立新的 權杖,然後使用名稱FLY_API_TOKEN
將其新增至 您的儲存庫密鑰。 -
將
SESSION_SECRET
、SUPABASE_URL
、SUPABASE_SERVICE_ROLE
、SUPABASE_ANON_PUBLIC
、SERVER_URL
和DATABASE_URL
新增至您的 Fly 應用程式密鑰注意: 若要尋找您的
SERVER_URL
,請前往 您的 fly.io 儀表板若要執行此操作,您可以執行下列命令
# production (--app name is resolved from fly.toml) fly secrets set SESSION_SECRET=$(openssl rand -hex 32) fly secrets set SUPABASE_URL="https://{YOUR_INSTANCE_NAME}.supabase.co" fly secrets set SUPABASE_SERVICE_ROLE="{SUPABASE_SERVICE_ROLE}" fly secrets set SUPABASE_ANON_PUBLIC="{SUPABASE_ANON_PUBLIC}" fly secrets set DATABASE_URL="postgres://postgres:{POSTGRES_PASSWORD}@db.{YOUR_INSTANCE_NAME}.supabase.co:5432/postgres" fly secrets set SERVER_URL="https://{YOUR_STAGING_SERVEUR_URL}" # staging (specify --app name) ** not mandatory if you don't want a staging environnement ** fly secrets set SESSION_SECRET=$(openssl rand -hex 32) --app supa-fly-stack-template-staging fly secrets set SUPABASE_URL="https://{YOUR_STAGING_INSTANCE_NAME}.supabase.co" --app supa-fly-stack-template-staging fly secrets set SUPABASE_SERVICE_ROLE="{STAGING_SUPABASE_SERVICE_ROLE}" --app supa-fly-stack-template-staging fly secrets set SUPABASE_ANON_PUBLIC="{STAGING_SUPABASE_ANON_PUBLIC}" --app supa-fly-stack-template-staging fly secrets set DATABASE_URL="postgres://postgres:{STAGING_POSTGRES_PASSWORD}@db.{STAGING_YOUR_INSTANCE_NAME}.supabase.co:5432/postgres" --app supa-fly-stack-template-staging fly secrets set SERVER_URL="https://{YOUR_STAGING_SERVEUR_URL}" --app supa-fly-stack-template-staging
如果您未安裝 openssl,您也可以使用 1password 來產生隨機密碼,只需將
$(openssl rand -hex 32)
替換為產生的密碼即可。
現在一切都已設定完成,您可以提交並將您的變更推送至您的儲存庫。每次提交到您的 main
分支都會觸發部署到您的生產環境,而每次提交到您的 dev
分支都會觸發部署到您的預備環境。
注意: 若要手動部署,只需執行
fly deploy
(這會部署 fly.toml 中定義的應用程式)
GitHub Actions
免責聲明:Github actions ==> 我不是這方面的專家。請仔細閱讀後再使用
我們使用 GitHub Actions 進行持續整合和部署。任何進入 main
分支的內容都會在執行測試/建置等之後部署到生產環境。dev
分支中的任何內容都會部署到預備環境。
👉 您必須為 Cypress 新增一些環境密鑰。 👈
將 SESSION_SECRET
、SUPABASE_URL
、SUPABASE_SERVICE_ROLE
、SUPABASE_ANON_PUBLIC
、SERVER_URL
和 DATABASE_URL
新增至 您的儲存庫密鑰
測試
Cypress
我們在此專案中使用 Cypress 進行端對端測試。您會在 cypress
目錄中找到這些測試。當您進行變更時,請在 cypress/e2e
目錄中新增至現有檔案或建立新檔案,以測試您的變更。
我們使用 @testing-library/cypress
來語意地選取頁面上的元素。
若要在開發環境中執行這些測試,請完成您的 .env
並執行 npm run test:e2e:dev
,這會啟動應用程式的開發伺服器以及 Cypress 用戶端。請確保資料庫如上所述在 docker 中執行。
我們也有一個公用程式可在測試結束時自動刪除使用者。只需確保在每個測試檔案中新增此公用程式即可
afterEach(() => {
cy.cleanupUser();
});
這樣一來,我們就可以保持您的測試資料庫乾淨,並讓您的測試彼此隔離。
Vitest
對於公用程式和個別元件的較低層級測試,我們使用 vitest
。我們透過 @testing-library/jest-dom
提供了 DOM 特定的斷言協助程式。
類型檢查
此專案使用 TypeScript。建議為您的編輯器設定 TypeScript,以便透過類型檢查和自動完成獲得絕佳的編輯器內體驗。若要在整個專案中執行類型檢查,請執行 npm run typecheck
。
程式碼檢查
此專案使用 ESLint 進行程式碼檢查。這在 .eslintrc.js
中設定。
格式化
我們在此專案中使用 Prettier 進行自動格式化。建議安裝編輯器外掛程式(例如 VSCode Prettier 外掛程式),以便在儲存時進行自動格式化。也有一個 npm run format
腳本,您可以使用它來格式化專案中的所有檔案。
開始使用 Supabase
您現在已準備好進一步行動,恭喜!
若要擴充您的 Prisma 架構並將變更套用至您的 Supabase 資料庫
-
在 ./app/database/schema.prisma 中進行變更
-
準備您的架構遷移
npm run db:prepare-migration
-
在 ./app/database/migrations 中檢查您的遷移
-
將此遷移套用至生產環境
npm run db:deploy-migration
如果您的權杖在 Supabase 儀表板中少於 1 小時(3600 秒)到期
如果您的權杖存留時間比我短(1 小時),您應該查看 ./app/modules/auth/session.server.ts 中的 REFRESH_ACCESS_TOKEN_THRESHOLD
,並設定您認為最適合您的使用案例的值。
Supabase RLS
您可能會問「我可以使用 RLS 與 Remix 嗎」。
答案是「可以」,但這會付出代價。
在伺服器端使用 Supabase SDK 查詢您的資料庫(對於那些使用 RLS 功能的使用者)會增加額外的延遲,因為會呼叫 Gotrue REST API,而不是直接呼叫 Postgres 資料庫(這很好,因為 Supabase SDK 最初是為那些沒有/不需要後端的人而設)。
在我的基準測試中,它會使我的頁面速度降低一倍。(與使用 Prisma 進行直接查詢相比,約 +200 毫秒)
使用魔法連結登入 Supabase
若要使使用魔法連結的註冊/登入運作,您需要將一些設定新增至您的 Supabase。您需要新增網站 URL 以及您的本機、測試和實際應用程式的重新導向 URL,這些 URL 將用於 OAuth。若要執行此操作,請瀏覽至驗證 > URL 設定並新增下列值