Remix Supa Fly 堆栈

此自述文件将很快重新编写

The Remix Indie Stack

了解有关 Remix 堆栈 的更多信息。

npx create-remix --template rphlmr/supa-fly-stack

堆栈内容

不喜欢堆栈中的某些部分?分叉它、更改它,并使用 `npx create-remix --template your/repo`!让它成为你自己的。

开发

  • 创建一个 Supabase 数据库(免费层级提供 2 个数据库)

    注意:仅用于玩转 Supabase 或用于 `staging` 和 `production` 的 2 个数据库。

    注意:用完免费层级了吗?也适用于 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` 是你在开发环境中的本地主机。它将适用于神奇链接登录。

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
    

这将在开发模式下启动你的应用程序,并在文件更改时重新构建资产。

数据库种子脚本创建了一个新用户,其中包含一些你可以用来入门的示例数据。

相关代码

这是一个非常简单的记笔记应用程序,但它很好地展示了如何使用 Prisma、Supabase 和 Remix 构建一个完整的堆栈应用程序。主要功能包括创建用户、登录和注销(处理访问和刷新令牌,并在到期时刷新)、创建和删除笔记。

部署

如果你是一位 Fly.io 专家,请按你所知的方式进行操作。

此 Remix 堆栈附带两个 GitHub Actions,用于自动将你的应用程序部署到生产和暂存环境。

在首次部署之前,你需要做几件事

  • 安装 Fly

  • 注册并登录 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 数据库上应用更改

如果你的令牌在不到 1 小时(在 Supabase 仪表板中为 3600 秒)内过期

如果你比我拥有更短的令牌生命周期(1 小时),你应该查看 ./app/modules/auth/session.server.ts 中的 `REFRESH_ACCESS_TOKEN_THRESHOLD` 并设置你认为最适合你的用例的值。

Supabase RLS

你可能会问“我可以在 Remix 中使用 RLS 吗”。

答案是“可以”,但它有一定的代价。

在服务器端使用 Supabase SDK 查询你的数据库(对于那些使用 RLS 功能的人)会增加额外的延迟,因为它是调用 Gotrue REST API 而不是直接调用 Postgres 数据库(这是可以的,因为 Supabase SDK 最初是为那些没有/不需要后端的人设计的)。

在我的基准测试中,这使得我的页面速度降低了一倍。(与使用 Prisma 的直接查询相比,增加了约 200 毫秒)

为了使使用神奇链接进行注册/登录正常工作,你需要在 Supabase 中添加一些配置。你需要添加站点 URL 以及将用于 OAuth 的本地、测试和实时应用程序的重定向 URL。为此,请导航到身份验证 > URL 配置,并添加以下值