5 个应用装进一个仓库 - 独立开发者的 Turborepo Monorepo
在一个仓库里管理多个应用和网站的 Turborepo Monorepo 搭建方法。共享公共配置、靠缓存省下构建时间、按应用分别部署,全部从实战视角整理。
核心摘要
一个人做多个应用,配置就会散落各处。用 Turborepo Monorepo 把 eslint 和 tsconfig 收进 packages 共享,turbo 缓存让没变的应用不再重复构建,--filter 实现按应用部署。
目录
一个人做应用,仓库会哗哗地涨。一个 App,一个网站,又一个 App… 然后 eslint 配置被你复制粘贴了五遍。我把这些全并进了一个 Monorepo。
散落的配置才是真问题
仓库一多,最疼的不是代码,是配置。
- eslint、prettier、tsconfig 每个仓库复制一份
- 改一条规则,就得挨个仓库巡回修改
- 公共 UI 和工具函数,发到 npm 又嫌太琐碎
Monorepo 把这一切变成在一个地方共享。
基本结构
apps/
├── web/ # 랜딩
├── blog/ # 이 블로그
├── wave/ # 오늘의 파도
└── ...
packages/
├── eslint-config/ # 공용 eslint
└── typescript-config/ # 공용 tsconfig
apps/* 是实际的部署产物,packages/* 是各应用共享的配置和代码。每个应用的 tsconfig.json 只做继承。
{ "extends": "@repo/typescript-config/nextjs.json" }
从此规则只在 packages 一个地方改。
turbo 缓存是核心
Turborepo 真正的武器是缓存。只要任务的输入(源码、配置)没变,它就直接复用上一次的结果。
turbo run build # 전체 빌드(바뀐 것만 실제로 돎)
turbo run build --filter=blog # blog 앱만
在 turbo.json 里声明任务间的依赖和输出就够了。
{
"tasks": {
"build": { "dependsOn": ["^build"], "outputs": [".next/**"] }
}
}
从第二次构建起,就是 "FULL TURBO",几秒钟收工。
按应用分别部署
虽然是一个仓库,部署仍然按应用分开。用 Docker 的话,turbo prune 可以只切出对应应用的子树,让镜像保持轻量。
turbo prune blog --docker # blog + 내부 의존성만 남긴 out/ 생성
这个博客就是这样切出来,用 Docker 部署到迷你主机上的。那部分故事在 自托管那篇文章 里。
小结
apps/*= 部署产物,packages/*= 共享配置- tsconfig 和 eslint 靠继承,只在一处维护
turbo缓存让没变的应用不再重复构建- 用
--filter和prune实现按应用部署
如果你一个人运营着多个产品,Monorepo 不是奢侈品,而是生存工具。
常见问题
有几个应用时上 Monorepo 才划算?
只要超过 2 个、出现了公共配置(eslint、tsconfig、UI),就已经划算了。核心在于配置只改一处,所有应用同步生效。
构建不会变慢吗?
反而更快。turbo 会缓存输入没有变化的任务结果,只重新构建发生变化的应用。
相关文章
- 💻 开发
用 Next.js 从零搭一个 MDX 博客 - 这个博客就是这么做的
不用 CMS,只靠 Markdown 文件就能运转的博客,用 Next.js 16 App Router 搭建的全过程。目录结构、MDX 配置、SEO,全部按实际代码流程整理。
- 💻 开发
在迷你主机上用 Docker + Cloudflare Tunnel 做自托管
只靠家里一台迷你主机,安全地对外发布多个 Web 服务的方法。不开放任何端口,用 Cloudflare Tunnel 挂上 HTTPS,再用 Docker Compose 跑起来。
- ☕ 日常
独立开发者的一天 - 一个人工作也不被耗尽的方法
没有上司,没有同事,一个人工作虽然自由,却很容易被耗尽。整理了我为了不丢掉节奏而坚持的日常安排和几条规则。