带有 Turborepo 的 Remix Gospel Stack
Remix TypeScript monorepo,具有 Turborepo 管道、Prisma、PostgreSQL 或 SQLite (Litefs)、Docker 部署到 Fly.io、pnpm、shadcn/ui TailwindCSS。
快速入门 (推荐)
pnpm create remix@latest --init-script --install --template https://github.com/PhilDL/remix-gospel-stack
:minidisc: 此仓库具有预设倾向
- 仅限 TypeScript。
- 仅与 pnpm 包管理器兼容,用于处理 monorepo 工作区。
- 使用 turborepo 管道 + 缓存来构建、lint、类型检查和测试 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 文件中,它可能与 yarn
和 npm
一起工作,但不能保证。
Turborepo 和 pnpm 工作区驱动的 Monorepo 架构
由-
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 未来标志均已激活
future: {
unstable_optimizeDeps: true,
v3_fetcherPersist: true,
v3_lazyRouteDiscovery: true,
v3_relativeSplatPath: true,
v3_throwAbortReason: true,
v3_singleFetch: true,
v3_routeConfig: true,
},
还有什么?
- Remix 应用 多区域 Fly 应用部署,使用 Docker
- 数据库有两种版本,您可以在安装时选择
- Remix 应用健康检查端点,用于 Fly 备份区域故障转移
- GitHub Actions,用于在合并到生产和预发布环境时部署 Remix 应用。
- 在 Remix 应用中使用 Playwright 进行端到端测试
- 在不同的包中使用 Vitest 和 Testing Library 进行单元测试。
- 使用 Prettier 进行代码格式化
- 使用 TypeScript 进行静态类型检查
警告 以下所有命令都应从 monorepo 根目录启动
开发
-
安装依赖项。
pnpm install
您还必须复制示例 .env.example
cp .env.example .env cp .env.example .env.docker
-
启动 postgresql docker 容器
pnpm run docker:db
注意:当 Docker 在后台设置容器时,npm 脚本将完成。请确保 Docker 已完成并且您的容器正在运行,然后再继续。
-
生成 prisma schema
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
然后按照提示进行操作
测试、类型检查、Lint、安装包...
查看 turbo.json
文件以查看可用的管道。
- 运行 Cypress 测试和 Dev
pnpm run test:e2e:dev --filter=@remix-gospel-stack/remix-app
- Lint 所有内容
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
文件夹中的 tsconfigs、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 数据库创建一个持久卷。运行以下命令(可以根据您的需要和您选择的区域更改 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 by @kentcdodds 的启发。
- 感谢 @shadcn 提供的令人惊叹的 组件库。
- UI 集成和一些良好实践无耻地借鉴了 @juliusmarminge 的项目 acme-corp monorepo。
支持
如果你觉得这个模板有用,请考虑给它一个 Star ⭐。谢谢!
免责声明
我绝不是 Monorepo、Docker 或 CI 方面的专家。这里提出的设置只是众多设置中的一种,并且可能可以改进 10 倍,但我正在自己摸索学习,所以如果你看到任何可能的改进,请提交 PR。我将非常感谢!