Aekor

Aekor
专注于用户阅读体验的响应式博客主题
  1. 首页
  2. Blog
  3. 正文

从零搭建全栈 Monorepo:Turborepo + Hono + Drizzle + Redis 实战指南

2026-06-02 19点热度 0人点赞 0条评论

一套代码,四种技术栈,一个仓库搞定前后端全栈开发。

在 2026 年的前端开发生态中,Monorepo 已经成为大型项目的标配。而 Turborepo 凭借其智能缓存和任务编排能力,成为了 Monorepo 构建工具的事实标准。

今天,我将手把手带你搭建一个生产级全栈 Monorepo,包含四种不同技术栈的应用,以及数据库、缓存等主流中间件。

项目技术栈一览

我们计划构建的应用包括:

  • Web 应用:TanStack Start(React 全栈框架,基于 Vite)
  • Admin 后台:Vue 3(轻量级后台管理)
  • Console 控制台:Next.js(企业级控制台)
  • Backend API:Hono(超快边缘计算框架)

基础设施:

  • 数据库:PostgreSQL + Drizzle ORM
  • 缓存 / 队列:Redis + BullMQ(可选)
  • 包管理器:pnpm(Workspace 原生支持)
  • 构建系统:Turborepo

第一步:初始化 Monorepo

使用官方脚手架快速创建项目:

# 使用 pnpm 创建(推荐)
pnpm dlx create-turbo@latest my-monorepo
cd my-monorepo

根据提示选择 pnpm 作为包管理器。推荐 pnpm 是因为它对 Workspace 有最好的支持,且依赖管理更高效。

第二步:规划项目结构

按照 Turborepo 的最佳实践,将代码分为 apps/(可部署应用)和 packages/(共享库):

my-monorepo/
├── apps/
│   ├── web/          # TanStack Start (React)
│   ├── admin/        # Vue 3 后台
│   ├── console/      # Next.js 控制台
│   └── backend/      # Hono API 服务
├── packages/
│   ├── ui/           # 共享 UI 组件库
│   ├── database/     # Drizzle ORM Schema + 客户端
│   ├── redis/        # Redis 客户端封装
│   ├── types/        # 共享 TypeScript 类型
│   └── config/       # 共享配置(ESLint, TypeScript, Tailwind)
├── package.json
├── pnpm-workspace.yaml
└── turbo.json

在 pnpm-workspace.yaml 中声明工作区:

packages:
  - "apps/*"
  - "packages/*"

apps/ 存放的是可部署的应用,packages/ 存放的是被应用消费的共享代码。这是一个约定而非强制要求,但它能帮你建立清晰的职责边界。

第三步:配置 Turborepo

turbo.json 是 Turborepo 的核心配置文件,定义了任务依赖关系和缓存策略。

{
  "$schema": "https://turbo.build/schema.json",
  "tasks": {
    "build": {
      "dependsOn": ["^build"],
      "outputs": [".next/**", "dist/**", "!.next/cache/**"]
    },
    "dev": {
      "cache": false,
      "persistent": true
    },
    "lint": {
      "outputs": []
    },
    "test": {
      "dependsOn": ["build"],
      "outputs": ["coverage/**"]
    },
    "type-check": {
      "dependsOn": ["^build"],
      "outputs": []
    }
  },
  "remoteCache": {
    "enabled": true
  }
}

理解 dependsOn 是掌握 Turborepo 的关键:

  • "dependsOn": ["^build"]:在执行当前包的 build 之前,先执行它所有 workspace 依赖包的 build
  • "dependsOn": ["build"](无 ^):在同一包内先执行 build,再执行当前任务

outputs 字段告诉 Turborepo 哪些目录需要缓存。Next.js 应用的 .next/** 和 Vite 应用的 dist/** 是最常见的输出目录。

第四步:创建共享数据库包(Drizzle ORM)

在 packages/database/ 中集中管理所有数据库 Schema 和迁移:

// packages/database/src/schema/index.ts
import { pgTable, uuid, varchar, timestamp, jsonb } from 'drizzle-orm/pg-core';

export const users = pgTable('users', {
  id: uuid('id').defaultRandom().primaryKey(),
  username: varchar('username', { length: 50 }).notNull().unique(),
  email: varchar('email', { length: 255 }).notNull().unique(),
  // ... 更多字段
});
// packages/database/src/client.ts
import { drizzle } from 'drizzle-orm/node-postgres';
import { Pool } from 'pg';
import * as schema from './schema';

const pool = new Pool({
  connectionString: process.env.DATABASE_URL,
});

export const db = drizzle(pool, { schema });

设计原则:将 Drizzle Schema 放在其所属应用的 src/db/ 下,由一个应用独享数据库绑定,其他应用通过 RPC 或 API 调用访问数据。如果使用共享 packages/database,要确保只有一个应用执行迁移操作。

第五步:配置 Redis 与 BullMQ

在 packages/redis/ 中封装 Redis 客户端,供后台应用和队列使用:

// packages/redis/src/index.ts
import Redis from 'ioredis';

export const redis = new Redis(process.env.REDIS_URL || 'redis://localhost:6379');

// 可选:BullMQ 队列
import { Queue } from 'bullmq';

export const emailQueue = new Queue('email', {
  connection: redis,
});

Drizzle ORM 从 0.44 版本开始原生支持查询缓存,可以直接集成 Upstash Redis 或自定义缓存层:

import { upstashCache } from 'drizzle-orm/cache/upstash';
import { drizzle } from 'drizzle-orm/...';

const db = drizzle(process.env.DB_URL!, {
  cache: upstashCache({
    url: process.env.UPSTASH_URL,
    token: process.env.UPSTASH_TOKEN,
    global: true,
    config: { ex: 60 } // 缓存 60 秒
  })
});

第六步:创建各个应用

在根目录的 package.json 中添加启动脚本,统一通过 Turborepo 管理:

{
  "scripts": {
    "dev": "turbo run dev",
    "build": "turbo run build",
    "lint": "turbo run lint",
    "type-check": "turbo run type-check",
    "clean": "turbo run clean && rm -rf node_modules"
  }
}

Web 应用(TanStack Start)

TanStack Start 基于 Vite,开发启动速度快,适合前端主站。

cd apps/web
pnpm create @tanstack/start@latest . --template react

Admin 后台(Vue 3)

使用 Vue 官方脚手架创建轻量级后台:

cd apps/admin
pnpm create vue@latest .
# 选择 TypeScript、Vue Router、Pinia 等特性

Console 控制台(Next.js)

Next.js 与 Turborepo 有官方级别的集成支持,缓存效果极佳:

cd apps/console
pnpm create next-app@latest . --typescript --tailwind --eslint

Backend API(Hono)

Hono 是超快的边缘计算 Web 框架,适合作为 API 网关:

cd apps/backend
pnpm create hono@latest .
# 选择 Node.js 运行时

在 Hono 中配置环境变量验证(推荐使用 Zod):

// apps/backend/src/env.ts
import { z } from 'zod';

export const env = z.object({
  DATABASE_URL: z.string().url(),
  REDIS_URL: z.string().url(),
  JWT_SECRET: z.string().min(32),
}).parse(process.env);

第七步:内部包引用

共享包通过 workspace: 协议在应用中被引用:

// apps/web/package.json
{
  "dependencies": {
    "@repo/ui": "workspace:*",
    "@repo/database": "workspace:*",
    "@repo/redis": "workspace:*",
    "@repo/types": "workspace:*"
  }
}

这种方式的优势是:一次修改,所有引用它的应用都能立即感知,无需发布到 npm。

第八步:启用远程缓存

Turborepo 的远程缓存可以让团队成员和 CI 共享构建结果,大幅提速:

# 登录 Vercel 账户(免费)
npx turbo login

# 链接当前仓库
npx turbo link

在 CI 中设置环境变量:

# GitHub Actions 示例
env:
  TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
  TURBO_TEAM: ${{ vars.TURBO_TEAM }}

启用远程缓存后,第一次构建会填充缓存,后续 PR 中未变更的包将直接从缓存恢复,CI 时间可减少 60-80%。

第九步:Docker 本地开发环境

使用 Docker Compose 一键启动 PostgreSQL 和 Redis:

# docker-compose.yml
version: '3.8'
services:
  postgres:
    image: postgres:16
    environment:
      POSTGRES_USER: myapp
      POSTGRES_PASSWORD: myapp
      POSTGRES_DB: myapp
    ports:
      - "5432:5432"
    volumes:
      - postgres_data:/var/lib/postgresql/data

  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"
    volumes:
      - redis_data:/data

volumes:
  postgres_data:
  redis_data:

开发与构建

启动所有应用:

pnpm dev

构建所有应用:

pnpm build

筛选特定应用(如只构建 backend):

pnpm build --filter=backend

总结与最佳实践

  1. apps/ 放可部署应用,packages/ 放共享代码:这是 Turborepo 社区最广泛接受的约定
  2. 根目录只放 repo 级工具:turbo、husky 等,应用的依赖装在各自目录下
  3. 使用 workspace:* 协议引用内部包:pnpm 的原生支持,无需手动同步版本
  4. 用 ^build 处理包依赖:确保上游包先构建,下游包再构建
  5. 尽早启用远程缓存:团队和 CI 都能受益,配置成本极低

这套架构让你能用一套代码管理四种技术栈的应用,同时享受 Drizzle 的类型安全数据库访问、Redis 的高效缓存,以及 Turborepo 带来的构建速度优势。无论是开发还是部署,都能获得顺畅的体验。

本作品采用 知识共享署名 4.0 国际许可协议 进行许可
标签: Drizzle ORM Hono Monorepo Next.js pnpm Redis TanStack Start Turborepo Vue 3 全栈开发 前端工程化
最后更新:2026-08-09

Aekor

这个人很懒,什么都没留下

点赞
< 上一篇
下一篇 >

文章评论

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
取消回复

使用AI教程

  • API报错解决方案
  • API 基础知识
  • API Key 获取

分类

  • Blog
  • TradingAgents-CN
  • 使用教程

COPYRIGHT © 2026 Aekor. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang