Remix Blues 堆栈

The Remix Blues Stack

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

npx create-remix@latest --template remix-run/blues-stack

堆栈包含哪些内容

不喜欢堆栈中的某些部分?可以 fork 它,修改它,然后使用 npx create-remix --template your/repo!把它变成你自己的。

快速入门

点击此按钮创建一个包含项目设置、已启动的 Postgres 以及已预安装的 Fly 的 Gitpod 工作区

Gitpod Ready-to-Code

开发

  • 首先运行堆栈的 remix.init 脚本,并将它对项目所做的更改提交到你的项目中。

    npx remix init
    git init # if you haven't already
    git add .
    git commit -m "Initialize project"
    
  • Docker 中启动 Postgres 数据库

    npm run docker
    

    注意:npm 脚本会在 Docker 在后台设置容器时完成。请确保 Docker 已完成并且你的容器正在运行,然后再继续操作。

  • 初始设置

    npm run setup
    
  • 运行首次构建

    npm run build
    
  • 启动开发服务器

    npm run dev
    

这会以开发模式启动你的应用程序,并在文件发生更改时重建资源。

数据库种子脚本创建了一个新用户,并提供了一些你可以用来入门的测试数据

如果你不想使用 Docker,也可以使用 Fly 的 Wireguard VPN 连接到开发数据库(甚至可以连接到你的生产数据库)。你可以在 这里 找到设置 Wireguard 的说明,以及在 这里 找到创建开发数据库的说明。

相关代码

这是一个非常简单的记事本应用程序,但它很好地展示了如何使用 Prisma 和 Remix 构建完整的堆栈应用程序。主要功能包括创建用户、登录和注销以及创建和删除笔记。

部署

这个 Remix 堆栈附带两个 GitHub Actions,它们负责自动将你的应用程序部署到生产环境和预发布环境。

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

  • 安装 Fly

  • 注册并登录 Fly

    fly auth signup
    

    注意:如果你有多个 Fly 帐户,请确保你在 Fly CLI 中登录的帐户与你在浏览器中登录的帐户相同。在你的终端中,运行 fly auth whoami,并确保电子邮件与你登录到浏览器的 Fly 帐户相匹配。

  • 在 Fly 上创建两个应用程序,一个用于预发布环境,另一个用于生产环境

    fly apps create blues-stack-template
    fly apps create blues-stack-template-staging
    

    注意:成功创建应用程序后,请仔细检查 fly.toml 文件,确保 app 键是你创建的生产应用程序的名称。这个堆栈 在初始化时会自动附加一个唯一的后缀,它可能与你在 Fly 上创建的应用程序不匹配。如果你存在这种不匹配,你可能会在你的 Github Actions CI 日志中看到 404 错误

  • 初始化 Git。

    git init
    
  • 创建一个新的 GitHub 仓库,然后将它添加为你的项目的远程仓库。不要立即推送你的应用程序!

    git remote add origin <ORIGIN_URL>
    
  • FLY_API_TOKEN 添加到你的 GitHub 仓库中。为此,请转到 Fly 上的用户设置,创建一个新的 令牌,然后将其添加到 你的仓库的秘密 中,名称为 FLY_API_TOKEN

  • SESSION_SECRET 添加到你的 Fly 应用程序的秘密中。为此,你可以运行以下命令

    fly secrets set SESSION_SECRET=$(openssl rand -hex 32) --app blues-stack-template
    fly secrets set SESSION_SECRET=$(openssl rand -hex 32) --app blues-stack-template-staging
    

    注意:创建预发布秘密时,你可能会收到 Fly CLI 的警告,如下所示

    WARN app flag 'blues-stack-template-staging' does not match app name in config file 'blues-stack-template'
    

    这仅仅意味着当前目录包含一个配置,该配置引用了我们在第一步中创建的生产应用程序。忽略此警告,继续创建秘密。

    如果你没有安装 openssl,也可以使用 1password 生成一个随机的秘密,只需将 $(openssl rand -hex 32) 替换为生成的秘密。

  • 为你的预发布环境和生产环境创建数据库。运行以下命令

    fly postgres create --name blues-stack-template-db
    fly postgres attach --app blues-stack-template blues-stack-template-db
    
    fly postgres create --name blues-stack-template-staging-db
    fly postgres attach --app blues-stack-template-staging blues-stack-template-staging-db
    

    注意:当你将预发布数据库附加到应用程序时,你将收到与在 fly set secret 步骤中相同的警告,原因相同。不要担心。继续操作!

Fly 会为你设置 DATABASE_URL 秘密。

现在一切都已设置好,你可以提交并推送更改到你的仓库。每次提交到你的 main 分支都会触发对生产环境的部署,而每次提交到你的 dev 分支都会触发对预发布环境的部署。

如果你在部署到 Fly 时遇到任何问题,请确保你已按照上述所有步骤操作,如果已操作,请将你部署的详细信息(包括你的应用程序名称)发布到 Fly 支持社区。他们通常反应很快,希望能帮助解决你部署过程中的任何问题和疑问。

多区域部署

一旦你的站点和数据库在一个区域中运行,就可以按照 Fly 的缩放多区域 PostgreSQL 文档中的步骤添加更多区域。

请务必为你的应用程序设置 PRIMARY_REGION 环境变量。你可以在 fly.toml 中使用 [env] 配置将其设置为要用作应用程序和数据库的主区域的区域。

在其他区域测试你的应用程序

安装 ModHeader 浏览器扩展(或类似的扩展),并使用它以设置 fly-prefer-region 头部的区域名称来加载你的应用程序。

你可以检查响应中的 x-fly-region 头部,以了解你的请求是在哪个区域处理的。

GitHub Actions

我们使用 GitHub Actions 进行持续集成和部署。进入 main 分支的任何内容将在运行测试/构建等操作后部署到生产环境。dev 分支中的任何内容都将部署到预发布环境。

测试

Cypress

我们在这个项目中使用 Cypress 进行端到端测试。你将在 cypress 目录中找到这些测试。在你进行更改时,请添加现有文件或在 cypress/e2e 目录中创建新文件来测试你的更改。

我们使用 @testing-library/cypress 来以语义的方式选择页面上的元素。

要在开发环境中运行这些测试,请运行 npm run test:e2e:dev,这将启动应用程序的开发服务器以及 Cypress 客户端。请确保数据库已在 docker 中运行,如上所述。

我们有一个实用程序,用于在无需执行登录流程的情况下测试经过身份验证的功能

cy.login();
// you are now logged in as a new user

我们还有一个实用程序,可以在测试结束时自动删除用户。请确保在每个测试文件中都添加以下内容

afterEach(() => {
  cy.cleanupUser();
});

这样,我们可以保持你的本地数据库干净,并确保你的测试彼此隔离。

Vitest

对于实用程序和单个组件的更底层测试,我们使用 vitest。我们通过 @testing-library/jest-dom 提供了针对 DOM 的断言帮助程序。

类型检查

这个项目使用 TypeScript。建议为你的编辑器设置 TypeScript,以便获得非常棒的编辑器体验,包括类型检查和自动完成功能。要对整个项目运行类型检查,请运行 npm run typecheck

代码风格检查

这个项目使用 ESLint 进行代码风格检查。它在 .eslintrc.js 中配置。

代码格式化

我们在这个项目中使用 Prettier 进行自动代码格式化。建议安装编辑器插件(例如 VSCode Prettier 插件),以便在保存时自动格式化代码。你还可以运行 npm run format 脚本,以便格式化项目中的所有文件。