Files
fullstack-starter/README.md
MAO Dongyang b967deb4b1 feat: 迁移数据库至 SQLite 并新增项目文档
- 将 Postgres 数据库替换为 SQLite
- 并同步添加 README 文档以优化项目初始化流程
2026-01-20 16:56:11 +08:00

243 lines
6.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Fullstack Starter (SQLite)
一个基于 **TanStack Start + Bun + Tauri + SQLite** 的全栈桌面应用脚手架。
包含一个完整的 **Todo List** 示例,展示了从前端到后端的完整数据流。
## 技术栈
| 层级 | 技术 |
|------|------|
| 前端框架 | React 19 + TanStack Router (文件路由) |
| 状态管理 | TanStack Query |
| 样式 | Tailwind CSS v4 |
| RPC 通信 | ORPC (类型安全,契约优先) |
| 数据库 | SQLite (Bun 内置) + Drizzle ORM |
| 桌面壳 | Tauri v2 |
| 运行时 | Bun |
| 构建 | Vite + Turbo |
## 快速开始
### 前置要求
- [Bun](https://bun.sh/) >= 1.0
- [Rust](https://www.rust-lang.org/) (仅 Tauri 桌面应用需要)
### 安装与运行
```bash
# 1. 克隆项目
git clone <your-repo-url>
cd fullstack-starter-SQLite
# 2. 安装依赖
bun install
# 3. 初始化数据库
bun run db:init
# 4. 启动开发服务器
bun run dev:vite # 仅 Web (http://localhost:3000)
bun run dev # Tauri 桌面应用 + Web
```
### 构建
```bash
bun run build:vite # 构建 Web 版本
bun run build # 构建 Tauri 桌面安装包
```
## 项目结构
```
├── src/
│ ├── components/ # 可复用组件
│ │ ├── Error.tsx # 错误边界组件
│ │ └── NotFound.tsx # 404 页面组件
│ │
│ ├── db/ # 数据库层
│ │ ├── index.ts # 数据库连接
│ │ └── schema/ # Drizzle 表定义
│ │ ├── index.ts # Schema 导出入口
│ │ └── todo.ts # Todo 表定义
│ │
│ ├── orpc/ # RPC 层 (后端 API)
│ │ ├── contracts/ # 契约定义 (输入/输出 Schema)
│ │ │ └── todo.ts # Todo API 契约
│ │ ├── handlers/ # 业务逻辑实现
│ │ │ └── todo.ts # Todo CRUD 处理器
│ │ ├── middlewares/ # 中间件
│ │ │ └── db.ts # 数据库注入中间件
│ │ ├── contract.ts # 契约聚合
│ │ ├── router.ts # 路由聚合
│ │ ├── client.ts # 同构客户端 (SSR/CSR)
│ │ ├── server.ts # 服务端实例
│ │ └── index.ts # 导出入口
│ │
│ ├── routes/ # 页面路由 (文件路由)
│ │ ├── __root.tsx # 根布局
│ │ ├── index.tsx # 首页 (Todo List)
│ │ └── api/
│ │ └── rpc.$.ts # RPC HTTP 端点
│ │
│ ├── integrations/ # 第三方库集成
│ ├── lib/ # 工具函数
│ ├── env.ts # 环境变量验证
│ ├── router.tsx # 路由配置
│ └── styles.css # 全局样式
├── scripts/
│ └── init-db.ts # 数据库初始化脚本
├── src-tauri/ # Tauri 桌面应用配置
├── data/ # SQLite 数据库文件 (gitignore)
└── drizzle.config.ts # Drizzle 配置
```
## 开发指南
### 添加新功能的步骤
以添加一个 "Note" 功能为例:
#### 1. 定义数据库 Schema
```typescript
// src/db/schema/note.ts
import { sql } from 'drizzle-orm'
import { integer, sqliteTable, text } from 'drizzle-orm/sqlite-core'
export const noteTable = sqliteTable('note', {
id: text('id').primaryKey().$defaultFn(() => crypto.randomUUID()),
content: text('content').notNull(),
createdAt: integer('created_at', { mode: 'timestamp' })
.notNull()
.default(sql`(unixepoch())`),
})
```
```typescript
// src/db/schema/index.ts
export * from './todo.ts'
export * from './note.ts' // 添加导出
```
#### 2. 定义 API 契约
```typescript
// src/orpc/contracts/note.ts
import { oc } from '@orpc/contract'
import { z } from 'zod'
export const note = {
list: oc.output(z.array(noteSchema)),
create: oc.input(z.object({ content: z.string() })).output(noteSchema),
}
```
#### 3. 实现业务逻辑
```typescript
// src/orpc/handlers/note.ts
import { os } from '@/orpc/server'
import { dbProvider } from '@/orpc/middlewares/db'
import { noteTable } from '@/db/schema'
export const list = os.note.list
.use(dbProvider)
.handler(async ({ context }) => {
return context.db.select().from(noteTable)
})
export const create = os.note.create
.use(dbProvider)
.handler(async ({ context, input }) => {
const [note] = await context.db.insert(noteTable).values(input).returning()
return note
})
```
#### 4. 注册到路由
```typescript
// src/orpc/contract.ts
import { note } from './contracts/note'
export const contract = { todo, note }
// src/orpc/router.ts
import * as note from './handlers/note'
export const router = os.router({ todo, note })
```
#### 5. 在页面中使用
```typescript
// src/routes/notes.tsx
import { orpc } from '@/orpc'
import { useSuspenseQuery, useMutation } from '@tanstack/react-query'
const NotesPage = () => {
const { data: notes } = useSuspenseQuery(orpc.note.list.queryOptions())
const createNote = useMutation(orpc.note.create.mutationOptions())
// ...
}
```
### 常用命令
| 命令 | 说明 |
|------|------|
| `bun run dev` | 启动 Tauri + Vite 开发服务器 |
| `bun run dev:vite` | 仅启动 Vite 开发服务器 |
| `bun run build` | 完整构建 (Tauri 桌面应用) |
| `bun run build:vite` | 仅构建 Web 版本 |
| `bun run db:init` | 初始化/重置数据库 |
| `bun run db:studio` | 打开 Drizzle Studio |
| `bun run typecheck` | TypeScript 类型检查 |
| `bun run fix` | 自动修复格式和 Lint 问题 |
### 代码规范
- **格式化**: 使用 Biome2 空格缩进,单引号
- **导入**: 使用 `@/*` 路径别名
- **组件**: 箭头函数组件
- **命名**: 文件 kebab-case组件 PascalCase
## 核心概念
### ORPC 数据流
```
前端组件
↓ useSuspenseQuery / useMutation
ORPC 客户端 (src/orpc/client.ts)
↓ 自动选择 SSR 直调 / CSR HTTP
契约验证 (src/orpc/contracts/)
↓ 输入/输出类型安全
处理器 (src/orpc/handlers/)
↓ 业务逻辑
中间件 (src/orpc/middlewares/)
↓ 注入数据库连接
Drizzle ORM
↓ 类型安全查询
SQLite 数据库
```
### 同构渲染
- **SSR**: 服务端直接调用 router无 HTTP 开销
- **CSR**: 客户端通过 `/api/rpc` 端点调用
### 数据库
- SQLite 文件存储在 `./data/app.db`
- 使用 WAL 模式提高并发性能
- 单例模式管理连接
## 许可证
MIT