带有 Turborepo 的 Remix 福音栈
带有 Turborepo 管道、Prisma、PostgreSQL 或 SQLite(Litefs)、Docker 部署到 Fly.io、pnpm、shadcn/ui TailwindCSS 的 Remix TypeScript 单仓库。
快速开始(推荐)
pnpm create remix@latest --init-script --install --template https://github.com/PhilDL/remix-gospel-stack
:minidisc: 这个仓库有自己的观点
- TypeScript 仅此而已。
- 仅与 pnpm 包管理器兼容,用于处理单仓库工作区。
- 使用 turborepo 管道 + 缓存来构建、lint、类型检查和测试单仓库。
(替代) 克隆仓库
git clone [email protected]:PhilDL/remix-gospel-stack.git
cd remix-gospel-stack
pnpm add -w @remix-run/dev
pnpm remix init
堆栈中有什么
这个堆栈是一个由 turborepo 和 pnpm 工作区 驱动的面向 Remix 的单仓库。包含一个准备好在 fly.io 上部署的 Remix 应用程序,通过构建 Docker 容器实现。
这个包 使用 pnpm
作为首选的包管理器 来管理工作区。如果您将工作区定义放在 package.json 文件中,它可能与 yarn
和 npm
一起使用,但不能保证。
Turborepo 和 pnpm 工作区驱动的单仓库架构
由-
apps
文件夹包含应用程序remix-app
: ESM 中的 Remix.run 应用程序。remix-vercel
: Remix.run 应用程序,准备部署到 Vercel。nextjs-app
: 一个 Next.js 应用程序
-
packages
文件夹包含示例ui
: 由 shadcn/ui 提供支持的 React UI 包示例。一些示例组件和 shadcn/ui Tailwind 配置作为 Tailwind 插件和预设导出。database
: 一个 Prisma 包装器,准备在其他包或应用程序中使用。与 tsup 捆绑在一起。可以是 PostgreSQL 或 SQLite // Litefs,取决于您在安装过程中选择什么。business
: 一个示例包,使用 Prismadatabase
作为依赖项,并使用类似于示例的存储库模式。internal-nobuild
: 一个示例包,它是纯粹的 TypeScript,没有构建步骤。包的main
入口点直接是src/index.ts
。Remix 通过其自己的构建步骤(使用 esbuild)来处理编译。这个包还包含使用 Vitest 的单元测试。Remix 使用tsconfig.json
路径来引用该项目及其类型。我建议在您不打算发布包时使用此类内部包。
-
config-packages
:- 具有不同预设配置的 Eslint 包。
- TS 配置,也具有不同的预设。
- Tailwind 配置。
还有什么?
- Remix 应用程序 多区域 Fly 应用程序部署,使用 Docker
- 数据库有两种类型,您可以在安装时选择
- Remix 应用程序健康检查端点,用于 Fly 备份区域回退
- GitHub Actions 用于在合并到生产环境和预发布环境时部署 Remix 应用程序。
- 使用 Playwright 在 Remix 应用程序中进行端到端测试
- 使用 Vitest 和 Testing Library 在不同的包中进行单元测试。
- 使用 Prettier 格式化代码
- 使用 TypeScript 进行静态类型检查
警告 以下所有命令都应该从 单仓库根目录 启动
开发
-
安装依赖项。
pnpm install
您还需要复制示例 .env.example
cp .env.example .env cp .env.example .env.docker
-
启动 postgresql docker 容器
pnpm run docker:db
注意: 当 Docker 在后台设置容器时,npm 脚本将完成。确保 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
文件夹。注意: 切换到 SQLite(Litefs)后,您必须再次运行
pnpm i --fix-lockfile
,因为 SQLite(Litefs)需要另一个包(litefs-js)。您可能还需要再次运行pnpm run setup
来生成第一个迁移。
创建包
内部包
turbo gen workspace --name @remix-gospel-stack/foobarbaz --type package --copy
然后按照提示进行操作
测试、类型检查、lint、安装包...
检查 turbo.json
文件以查看可用的管道。
- 运行 Cypress 测试和开发
pnpm run test:e2e:dev --filter=@remix-gospel-stack/remix-app
- lint 所有内容
pnpm run lint
- 对整个单仓库进行类型检查
pnpm run typecheck
- 测试整个单仓库
pnpm run test or pnpm run test:dev
- 如何在 Remix 应用程序中安装 npm 包?
pnpm add dayjs --filter @remix-gospel-stack/remix-app
- 调整
config-package
文件夹中的 tsconfigs、eslint 配置。然后任何包或应用程序都将从这些配置中扩展。
在 fly.io 上部署 - PostgreSQL
警告 以下所有命令都应该从 单仓库根目录 启动
在您第一次部署之前,您需要做几件事
-
首先注册 fly CLI
fly auth signup
-
在 Fly 上创建两个应用程序,一个用于预发布环境,一个用于生产环境
fly apps create remix-gospel-stack fly apps create remix-gospel-stack-staging
注意: 成功创建应用程序后,请仔细检查
fly.toml
文件,确保app
键是您创建的生产应用程序的名称。这个栈 在初始化时会自动附加一个唯一的后缀,这可能与您在 Fly 上创建的应用程序不匹配。如果您存在这种不匹配,您可能会在 Github Actions CI 日志中看到 404 错误。 -
初始化 Git。
git init
-
创建一个新的 GitHub 仓库,然后将其添加为项目的远程仓库。请勿推送您的应用程序!
git remote add origin <ORIGIN_URL>
-
向您的 GitHub 仓库添加一个
FLY_API_TOKEN
。为此,请转到您在 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
警告 以下所有命令都应该从 单仓库根目录 启动
在您第一次部署之前,您需要做几件事
-
首先注册 fly CLI
fly auth signup
-
在 Fly 上创建两个应用程序,一个用于预发布环境,一个用于生产环境
fly apps create remix-gospel-stack fly apps create remix-gospel-stack-staging
注意: 成功创建应用程序后,请仔细检查
fly.toml
文件,确保app
键是您创建的生产应用程序的名称。这个栈 在初始化时会自动附加一个唯一的后缀,这可能与您在 Fly 上创建的应用程序不匹配。如果您存在这种不匹配,您可能会在 Github Actions CI 日志中看到 404 错误。 -
初始化 Git。
git init
-
创建一个新的 GitHub 仓库,然后将其添加为项目的远程仓库。请勿推送您的应用程序!
git remote add origin <ORIGIN_URL>
-
向您的 GitHub 仓库添加一个
FLY_API_TOKEN
。为此,请转到您在 Fly 上的用户设置,创建一个新的 令牌,然后将其添加到 您的仓库机密 中,名称为FLY_API_TOKEN
。
为您的预发布环境和生产环境的 sqlite 数据库创建一个持久卷。运行以下命令(您可以根据自己的需求和选择的区域调整 GB 大小 (https://fly.io/docs/reference/regions/)。如果确实更改了区域,请确保在 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 链接
了解 Turborepo 的强大功能
感谢
- ESM 设置深受 epic-stack 的启发,该栈由 @kentcdodds 创建
- 感谢 @shadcn 提供出色的 组件库。
- UI 集成和一些最佳实践是从 @juliusmarminge 的项目 acme-corp 多仓库 中借鉴而来。
支持
如果您发现该模板有用,请考虑为它点个 Star ⭐。谢谢!
免责声明
我并不是 Monorepo、Docker 或 CI 方面的专家。这里提出的设置只是众多方法中的一种,可能还有很大的改进空间,但我正在边学边做,如果您发现任何可能的改进,请提交 PR。我会非常感谢您的贡献!