forked from imbytecat/fullstack-starter
feat: 迁移数据库至 SQLite 并新增项目文档
- 将 Postgres 数据库替换为 SQLite - 并同步添加 README 文档以优化项目初始化流程
This commit is contained in:
242
README.md
Normal file
242
README.md
Normal file
@@ -0,0 +1,242 @@
|
||||
# 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 问题 |
|
||||
|
||||
### 代码规范
|
||||
|
||||
- **格式化**: 使用 Biome,2 空格缩进,单引号
|
||||
- **导入**: 使用 `@/*` 路径别名
|
||||
- **组件**: 箭头函数组件
|
||||
- **命名**: 文件 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
|
||||
Reference in New Issue
Block a user