@lightfish/cli 0.0.5 → 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/create-lightfish.js +133 -60
- package/dist/lightfish.js +160 -87
- package/dist/templates/react-vite/.agents/skills/lightfish-server/SKILL.md +447 -0
- package/dist/templates/react-vite/.vscode/settings.json +42 -0
- package/dist/templates/react-vite/AGENTS.md +254 -0
- package/dist/templates/react-vite/README.md +150 -0
- package/dist/templates/react-vite/_gitignore +23 -0
- package/dist/templates/react-vite/eslint.config.js +25 -0
- package/dist/templates/react-vite/index.html +13 -0
- package/dist/templates/react-vite/lightfish-server.config.js +6 -0
- package/dist/templates/react-vite/package.json +41 -0
- package/dist/templates/react-vite/pnpm-lock.yaml +3649 -0
- package/dist/templates/react-vite/public/favicon.svg +1 -0
- package/dist/templates/react-vite/public/icons.svg +24 -0
- package/dist/templates/react-vite/server/router/hello/index.ts +20 -0
- package/dist/templates/react-vite/server/schema/index.ts +18 -0
- package/dist/templates/react-vite/src/assets/hero.png +0 -0
- package/dist/templates/react-vite/src/assets/react.svg +1 -0
- package/dist/templates/react-vite/src/assets/vite.svg +1 -0
- package/dist/templates/react-vite/src/main.css +1 -0
- package/dist/templates/react-vite/src/main.tsx +43 -0
- package/dist/templates/react-vite/src/pages/example/index.tsx +26 -0
- package/dist/templates/react-vite/src/pages/example/layout.tsx +31 -0
- package/dist/templates/react-vite/src/pages/example/model.ts +20 -0
- package/dist/templates/react-vite/src/pages/index.tsx +17 -0
- package/dist/templates/react-vite/src/pages/layout.tsx +15 -0
- package/dist/templates/react-vite/tsconfig.app.json +30 -0
- package/dist/templates/react-vite/tsconfig.json +7 -0
- package/dist/templates/react-vite/tsconfig.node.json +24 -0
- package/dist/templates/react-vite/vite.config.ts +61 -0
- package/package.json +3 -2
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
# AGENTS.md — template-vite-server
|
|
2
|
+
|
|
3
|
+
## 项目概览
|
|
4
|
+
|
|
5
|
+
### 模板项目开发约定
|
|
6
|
+
|
|
7
|
+
- `src/pages/index.tsx` 是**首页占位页**,仅用于项目初始化时展示,应替换为真实业务首页。
|
|
8
|
+
- `src/pages/example/` 是**示例路由模块**,仅用于演示 `layout + model + index` 的标准写法,新建项目时可直接删除或覆盖。
|
|
9
|
+
- 不要把示例代码当作已实现的业务功能去修改或补全。
|
|
10
|
+
- 新增功能时,遵循本文件约定的目录结构、命名规范和分层方式。
|
|
11
|
+
|
|
12
|
+
## 全栈架构
|
|
13
|
+
|
|
14
|
+
本项目是前端 + 后端一体化的全栈模板:
|
|
15
|
+
|
|
16
|
+
- **前端**:Vite + React + TypeScript + Tailwind CSS,使用 `@lightfish/router` 文件系统路由和 `@lightfish/react-model` 状态管理。
|
|
17
|
+
- **后端**:`@lightfish/server` 约定式路由 + Drizzle ORM + PostgreSQL,接口文件放在 `server/router/`。
|
|
18
|
+
|
|
19
|
+
### 完整目录结构
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
项目根/
|
|
23
|
+
├── src/ # 前端应用
|
|
24
|
+
├── server/ # lightfish-server 后端
|
|
25
|
+
│ ├── schema/index.ts # Drizzle ORM 数据库 Schema
|
|
26
|
+
│ └── router/ # 约定式路由
|
|
27
|
+
│ └── <module>/index.ts
|
|
28
|
+
├── lightfish-server.config.js # 后端配置
|
|
29
|
+
└── vite.config.ts # 前端构建配置
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### 常用命令
|
|
33
|
+
|
|
34
|
+
| 命令 | 说明 |
|
|
35
|
+
| --------------- | --------------------------------- |
|
|
36
|
+
| `pnpm dev` | 启动前端开发服务器 |
|
|
37
|
+
| `pnpm build` | 构建前端生产包 |
|
|
38
|
+
| `pnpm lint` | 运行 ESLint |
|
|
39
|
+
| `pnpm db:push` | 同步数据库 schema(改 schema 后必做) |
|
|
40
|
+
|
|
41
|
+
### 前后端协作流程
|
|
42
|
+
|
|
43
|
+
1. 在 `server/schema/index.ts` 定义数据表。
|
|
44
|
+
2. 执行 `pnpm db:push` 同步到数据库。
|
|
45
|
+
3. 在 `server/router/<模块>/index.ts` 写接口 handler。
|
|
46
|
+
4. 前端通过 `@lightfish/server/api` 的 `apiRequest` 调用接口。
|
|
47
|
+
|
|
48
|
+
后端开发详细规范(schema、路由、handler、apiRequest、生产环境约束)见 `.agents/skills/lightfish-server/SKILL.md`。
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
| 能力 | 方案 |
|
|
53
|
+
| ----------- | ----------------------------------------------- |
|
|
54
|
+
| 构建工具 | Vite 8 |
|
|
55
|
+
| UI 框架 | React 19 |
|
|
56
|
+
| 类型系统 | TypeScript 6 |
|
|
57
|
+
| 路由方案 | `@lightfish/router` — 文件系统路由 |
|
|
58
|
+
| 状态管理 | `@lightfish/react-model` — 桥接 hook 到 Context |
|
|
59
|
+
| 样式方案 | Tailwind CSS 4 |
|
|
60
|
+
| 代码规范 | ESLint 10 |
|
|
61
|
+
| 后端 / ORM | `@lightfish/server` + Drizzle ORM + PostgreSQL |
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## 1. 路由 & 页面结构(文件系统路由)
|
|
66
|
+
|
|
67
|
+
### 路由映射规则
|
|
68
|
+
|
|
69
|
+
| 文件路径 | 路由 |
|
|
70
|
+
| --------------------------------- | ----------------------------------------- |
|
|
71
|
+
| `src/pages/index.tsx` | `/` |
|
|
72
|
+
| `src/pages/example/index.tsx` | `/example` |
|
|
73
|
+
| `src/pages/example/layout.tsx` | `/example` 及其子路由的**布局壳** |
|
|
74
|
+
| `src/pages/example/404.tsx` | `/example/*`(未匹配兜底) |
|
|
75
|
+
| `src/pages/example/settings.tsx` | 页面元信息(用于设置 `document.title`) |
|
|
76
|
+
| `src/pages/blog/[id]/index.tsx` | `/blog/:id` |
|
|
77
|
+
|
|
78
|
+
> 注意:`@lightfish/router` 只识别 `index.tsx` 作为页面入口,单文件页面(如 `example.tsx`、`blog/[id].tsx`)不会生成路由;`settings.tsx` 也不是独立路由。
|
|
79
|
+
|
|
80
|
+
### layout.tsx — 布局壳
|
|
81
|
+
|
|
82
|
+
`layout.tsx` 渲染**外围框架**(导航栏、侧边栏、Provider 包裹等),内部使用 `<Outlet />` 渲染子路由页面。
|
|
83
|
+
|
|
84
|
+
```tsx
|
|
85
|
+
// src/pages/example/layout.tsx
|
|
86
|
+
export default function ExampleLayout() {
|
|
87
|
+
return (
|
|
88
|
+
<div className="flex h-screen">
|
|
89
|
+
<aside>侧边栏</aside>
|
|
90
|
+
<main className="flex-1">
|
|
91
|
+
<Outlet /> {/* ← 子路由在此渲染 */}
|
|
92
|
+
</main>
|
|
93
|
+
</div>
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
**layout.tsx 的职责边界:**
|
|
99
|
+
|
|
100
|
+
- ✅ 渲染布局框架(flex、grid、导航等)
|
|
101
|
+
- ✅ 包裹 `<Outlet />` 渲染子页面
|
|
102
|
+
- ✅ 包裹 `<Provider>` 提供**该路由模块**的状态
|
|
103
|
+
- ❌ 不能写页面内容(内容在 index.tsx 或子路由中)
|
|
104
|
+
- ❌ 不能写请求逻辑或业务状态管理(在 model.ts 中)
|
|
105
|
+
|
|
106
|
+
### layout + model + index 标准模式
|
|
107
|
+
|
|
108
|
+
```
|
|
109
|
+
pages/example/
|
|
110
|
+
├── model.ts ← ① 定义 hook + createCustomModel
|
|
111
|
+
├── layout.tsx ← ② <Provider><Outlet /></Provider>
|
|
112
|
+
└── index.tsx ← ③ 取状态 + 渲染 UI
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## 2. 状态管理(@lightfish/react-model)
|
|
118
|
+
|
|
119
|
+
### 基本原理
|
|
120
|
+
|
|
121
|
+
`createCustomModel(useHook)` 把自定义 hook 桥接到 React Context:
|
|
122
|
+
|
|
123
|
+
```ts
|
|
124
|
+
import { createCustomModel } from "@lightfish/react-model";
|
|
125
|
+
|
|
126
|
+
function useMyHook(props: { count: number }) {
|
|
127
|
+
// 任意逻辑、useState、useEffect...
|
|
128
|
+
return { count, increment: () => {} };
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export const { Provider, useModel } = createCustomModel(useMyHook);
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
**Provider 的 value 会作为参数传给 hook:**
|
|
135
|
+
|
|
136
|
+
```tsx
|
|
137
|
+
<Provider value={{ count: 0 }}>
|
|
138
|
+
<Child />
|
|
139
|
+
</Provider>
|
|
140
|
+
// → useMyHook({ count: 0 }) 在内部运行,返回值注入 Context
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### 标准三层结构
|
|
144
|
+
|
|
145
|
+
```ts
|
|
146
|
+
// model.ts — 定义状态 + hook
|
|
147
|
+
import { createCustomModel } from "@lightfish/react-model";
|
|
148
|
+
|
|
149
|
+
// 注意:hook 名用 useXxx,对应 useModel 会命名为 useXxxModel
|
|
150
|
+
function useExample(initial: { id: string }) {
|
|
151
|
+
const [messages, setMessages] = useState<UIMessage[]>([]);
|
|
152
|
+
const [collapsed, setCollapsed] = useState(false);
|
|
153
|
+
|
|
154
|
+
return {
|
|
155
|
+
messages,
|
|
156
|
+
collapsed,
|
|
157
|
+
setCollapsed,
|
|
158
|
+
send: (text: string) => {
|
|
159
|
+
/* ... */
|
|
160
|
+
},
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export const { Provider: ExampleProvider, useModel: useExampleModel } =
|
|
165
|
+
createCustomModel(useExample);
|
|
166
|
+
// ↑ 命名规则:XxxProvider ↑ 命名规则:useXxxModel
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
```tsx
|
|
170
|
+
// layout.tsx — 注入状态
|
|
171
|
+
import { ExampleProvider } from "./model";
|
|
172
|
+
|
|
173
|
+
export default function ExampleLayout() {
|
|
174
|
+
return (
|
|
175
|
+
<ExampleProvider value={{ id: "default" }}>
|
|
176
|
+
<Outlet />
|
|
177
|
+
</ExampleProvider>
|
|
178
|
+
);
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
```tsx
|
|
183
|
+
// index.tsx — 消费状态
|
|
184
|
+
import { useExampleModel } from "./model";
|
|
185
|
+
|
|
186
|
+
export default function ExamplePage() {
|
|
187
|
+
const { messages, collapsed, send } = useExampleModel();
|
|
188
|
+
// ...
|
|
189
|
+
}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### 常见错误
|
|
193
|
+
|
|
194
|
+
| ❌ 错误写法 | ✅ 正确写法 |
|
|
195
|
+
| --------------------------------------------------- | -------------------------------------------------------------- |
|
|
196
|
+
| `layout.tsx` 里直接写页面 UI | `layout.tsx` 只写布局 + `<Outlet />` |
|
|
197
|
+
| `layout.tsx` 里用 `useExampleModel()` | `layout.tsx` 只包裹 `<Provider>`,子页面通过 `useModel()` 消费 |
|
|
198
|
+
| `model.ts` 里导出 hook 但不调用 `createCustomModel` | 必须调用 `createCustomModel` 生成 Provider + useModel |
|
|
199
|
+
| 把 Provider 放在 `index.tsx` 里 | Provider 放在 `layout.tsx` 里,确保**整个**路由模块共享 |
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## 3. 组件 & 逻辑内聚原则
|
|
204
|
+
|
|
205
|
+
**默认策略:就近内聚,延迟抽离。全部写在一个文件里,直到被复用才抽离。**
|
|
206
|
+
|
|
207
|
+
- 页面组件、请求逻辑、UI 片段**先写在一个文件里**
|
|
208
|
+
- 1 处使用 → 就地写
|
|
209
|
+
- 2 处及以上 → 抽离到对应目录
|
|
210
|
+
- UI 组件 → `src/components/`
|
|
211
|
+
- hooks → `src/hooks/`
|
|
212
|
+
- 工具函数 → `src/utils/`
|
|
213
|
+
- 类型 → `src/types/`
|
|
214
|
+
|
|
215
|
+
**例外:** 只有 `model.ts` 必须独立文件(因为 createCustomModel 要求单独导出 Provider)。
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
## 4. 样式规范
|
|
220
|
+
|
|
221
|
+
- 使用 Tailwind CSS 4 utility classes
|
|
222
|
+
- 复杂样式用 `@utility` 指令在 `src/main.css` 中定义
|
|
223
|
+
- 不要用 `style={{}}` 内联 style(除非动态计算)
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
## 5. 代码组织
|
|
228
|
+
|
|
229
|
+
```
|
|
230
|
+
src/
|
|
231
|
+
├── pages/ # 页面组件(文件路由)
|
|
232
|
+
│ ├── index.tsx # /
|
|
233
|
+
│ ├── layout.tsx # 根布局
|
|
234
|
+
│ └── example/ # 示例模块(新项目可删除)
|
|
235
|
+
│ ├── model.ts # useExampleModel + createCustomModel → ExampleProvider + useExampleModel
|
|
236
|
+
│ ├── layout.tsx # <ExampleProvider><Outlet /></ExampleProvider>
|
|
237
|
+
│ └── index.tsx # /example — 示例 UI
|
|
238
|
+
├── components/ # 共享组件(仅复用时抽离)
|
|
239
|
+
│ └── ai-elements/ # AI Elements CLI 生成的组件
|
|
240
|
+
├── hooks/ # 共享 hooks(仅复用时抽离)
|
|
241
|
+
├── models/ # 全局状态模型(跨路由共享)
|
|
242
|
+
├── utils/ # 工具函数
|
|
243
|
+
├── types/ # 共享类型定义
|
|
244
|
+
├── main.css # 全局样式(Tailwind + @utility)
|
|
245
|
+
└── main.tsx # 应用入口
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
## 6. 开发原则
|
|
251
|
+
|
|
252
|
+
- **默认一个文件** — UI、逻辑、状态写在同一个页面文件里,不复用就不抽离
|
|
253
|
+
- **类型安全** — 充分利用 TypeScript 6
|
|
254
|
+
- **可读性优先** — 代码清晰比聪明重要
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# template-vite-server
|
|
2
|
+
|
|
3
|
+
基于 Vite 8 + React 19 + TypeScript 6 的全栈项目模板,前端使用文件系统路由与轻量级状态管理,后端使用 `@lightfish/server` 约定式路由。
|
|
4
|
+
|
|
5
|
+
> 这是模板项目,所有示例代码均可放心修改或删除。
|
|
6
|
+
|
|
7
|
+
## 技术栈
|
|
8
|
+
|
|
9
|
+
| 能力 | 方案 |
|
|
10
|
+
| ----------- | ----------------------------------------------- |
|
|
11
|
+
| 构建工具 | Vite 8 |
|
|
12
|
+
| UI 框架 | React 19 |
|
|
13
|
+
| 类型系统 | TypeScript 6 |
|
|
14
|
+
| 路由方案 | `@lightfish/router` — 文件系统路由 |
|
|
15
|
+
| 状态管理 | `@lightfish/react-model` — 桥接 hook 到 Context |
|
|
16
|
+
| 样式方案 | Tailwind CSS 4 |
|
|
17
|
+
| 代码规范 | ESLint 10 |
|
|
18
|
+
| 后端 / ORM | `@lightfish/server` + Drizzle ORM + PostgreSQL |
|
|
19
|
+
|
|
20
|
+
## 快速开始
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
# 安装依赖
|
|
24
|
+
pnpm install
|
|
25
|
+
|
|
26
|
+
# 启动前端开发服务器(默认 http://localhost:8000)
|
|
27
|
+
pnpm dev
|
|
28
|
+
|
|
29
|
+
# 构建生产版本
|
|
30
|
+
pnpm build
|
|
31
|
+
|
|
32
|
+
# 预览构建产物
|
|
33
|
+
pnpm preview
|
|
34
|
+
|
|
35
|
+
# 代码检查
|
|
36
|
+
pnpm lint
|
|
37
|
+
|
|
38
|
+
# 同步数据库 schema(修改 schema 后执行)
|
|
39
|
+
pnpm db:push
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## 项目结构
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
项目根/
|
|
46
|
+
├── src/ # 前端应用
|
|
47
|
+
│ ├── pages/ # 页面组件(文件系统路由)
|
|
48
|
+
│ │ ├── index.tsx # / 首页占位页(请替换为真实业务首页)
|
|
49
|
+
│ │ ├── layout.tsx # 根布局
|
|
50
|
+
│ │ └── example/ # 示例路由模块(可直接删除)
|
|
51
|
+
│ │ ├── model.ts # 局部状态模型
|
|
52
|
+
│ │ ├── layout.tsx # 布局壳(Provider + Outlet)
|
|
53
|
+
│ │ └── index.tsx # 示例页面 UI
|
|
54
|
+
│ ├── components/ # 共享组件(复用时抽离)
|
|
55
|
+
│ ├── hooks/ # 共享 hooks(复用时抽离)
|
|
56
|
+
│ ├── models/ # 全局状态模型(跨路由共享)
|
|
57
|
+
│ ├── utils/ # 工具函数
|
|
58
|
+
│ ├── types/ # 共享类型定义
|
|
59
|
+
│ ├── main.css # 全局样式(Tailwind + @utility)
|
|
60
|
+
│ └── main.tsx # 应用入口
|
|
61
|
+
├── server/ # lightfish-server 后端
|
|
62
|
+
│ ├── schema/index.ts # Drizzle ORM 数据库 Schema
|
|
63
|
+
│ └── router/ # 约定式路由
|
|
64
|
+
│ └── <module>/index.ts
|
|
65
|
+
├── lightfish-server.config.js # 后端配置
|
|
66
|
+
└── vite.config.ts # 前端构建配置
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## 路由
|
|
70
|
+
|
|
71
|
+
使用 `@lightfish/router` 实现文件系统路由,页面文件自动映射为路由:
|
|
72
|
+
|
|
73
|
+
| 文件路径 | 路由 |
|
|
74
|
+
| --------------------------------- | ----------------------------------------- |
|
|
75
|
+
| `src/pages/index.tsx` | `/` |
|
|
76
|
+
| `src/pages/example/index.tsx` | `/example` |
|
|
77
|
+
| `src/pages/example/layout.tsx` | `/example` 及其子路由的**布局壳** |
|
|
78
|
+
| `src/pages/example/404.tsx` | `/example/*`(未匹配兜底) |
|
|
79
|
+
| `src/pages/example/settings.tsx` | 页面元信息(用于设置 `document.title`) |
|
|
80
|
+
| `src/pages/blog/[id]/index.tsx` | `/blog/:id` |
|
|
81
|
+
|
|
82
|
+
> `@lightfish/router` 只识别 `index.tsx` 作为页面入口。
|
|
83
|
+
|
|
84
|
+
## 状态管理
|
|
85
|
+
|
|
86
|
+
使用 `@lightfish/react-model` 将自定义 hook 桥接到 React Context:
|
|
87
|
+
|
|
88
|
+
```tsx
|
|
89
|
+
// model.ts
|
|
90
|
+
import { createCustomModel } from "@lightfish/react-model";
|
|
91
|
+
import { useState } from "react";
|
|
92
|
+
|
|
93
|
+
function useExample(initial: { id: string }) {
|
|
94
|
+
const [count, setCount] = useState(0);
|
|
95
|
+
return { count, increment: () => setCount((c) => c + 1) };
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export const { Provider: ExampleProvider, useModel: useExampleModel } =
|
|
99
|
+
createCustomModel(useExample);
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
```tsx
|
|
103
|
+
// layout.tsx — 注入状态
|
|
104
|
+
import { ExampleProvider } from "./model";
|
|
105
|
+
|
|
106
|
+
export default function ExampleLayout() {
|
|
107
|
+
return (
|
|
108
|
+
<ExampleProvider value={{ id: "default" }}>
|
|
109
|
+
<Outlet />
|
|
110
|
+
</ExampleProvider>
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// index.tsx — 消费状态
|
|
115
|
+
import { useExampleModel } from "./model";
|
|
116
|
+
|
|
117
|
+
export default function ExamplePage() {
|
|
118
|
+
const { count, increment } = useExampleModel();
|
|
119
|
+
// ...
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## 后端开发
|
|
124
|
+
|
|
125
|
+
后端接口写在 `server/router/<模块>/index.ts`,通过 `@lightfish/server/api` 的 `apiRequest` 在前端调用。详细规范见 `.agents/skills/lightfish-server/SKILL.md`。
|
|
126
|
+
|
|
127
|
+
前后端协作流程:
|
|
128
|
+
|
|
129
|
+
1. 在 `server/schema/index.ts` 定义数据表。
|
|
130
|
+
2. 执行 `pnpm db:push` 同步到数据库。
|
|
131
|
+
3. 在 `server/router/<模块>/index.ts` 写接口 handler。
|
|
132
|
+
4. 前端通过 `apiRequest` 调用接口。
|
|
133
|
+
|
|
134
|
+
## 样式
|
|
135
|
+
|
|
136
|
+
- 使用 Tailwind CSS 4 utility classes
|
|
137
|
+
- 复杂样式用 `@utility` 指令在 `src/main.css` 中定义
|
|
138
|
+
- 默认暗色主题,Inter Variable 字体
|
|
139
|
+
|
|
140
|
+
## 开发原则
|
|
141
|
+
|
|
142
|
+
- **默认一个文件** — UI、逻辑、状态写在同一个页面文件里,不复用就不抽离
|
|
143
|
+
- **类型安全** — 充分利用 TypeScript 6
|
|
144
|
+
- **可读性优先** — 代码清晰比聪明重要
|
|
145
|
+
|
|
146
|
+
## 重要提示
|
|
147
|
+
|
|
148
|
+
- `src/pages/index.tsx` 是**首页占位页**,请替换为真实业务首页。
|
|
149
|
+
- `src/pages/example/` 是**示例路由模块**,仅用于演示 `layout + model + index` 的标准写法,新建项目时可直接删除或覆盖。
|
|
150
|
+
- 不要把示例代码当作已实现的业务功能去修改或补全。
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Logs
|
|
2
|
+
logs
|
|
3
|
+
*.log
|
|
4
|
+
npm-debug.log*
|
|
5
|
+
yarn-debug.log*
|
|
6
|
+
yarn-error.log*
|
|
7
|
+
pnpm-debug.log*
|
|
8
|
+
lerna-debug.log*
|
|
9
|
+
|
|
10
|
+
node_modules
|
|
11
|
+
dist
|
|
12
|
+
dist-ssr
|
|
13
|
+
*.local
|
|
14
|
+
|
|
15
|
+
# Editor directories and files
|
|
16
|
+
!.vscode/extensions.json
|
|
17
|
+
.idea
|
|
18
|
+
.DS_Store
|
|
19
|
+
*.suo
|
|
20
|
+
*.ntvs*
|
|
21
|
+
*.njsproj
|
|
22
|
+
*.sln
|
|
23
|
+
*.sw?
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import js from "@eslint/js";
|
|
2
|
+
import globals from "globals";
|
|
3
|
+
import reactHooks from "eslint-plugin-react-hooks";
|
|
4
|
+
import reactRefresh from "eslint-plugin-react-refresh";
|
|
5
|
+
import tseslint from "typescript-eslint";
|
|
6
|
+
import { defineConfig, globalIgnores } from "eslint/config";
|
|
7
|
+
|
|
8
|
+
export default defineConfig([
|
|
9
|
+
globalIgnores(["dist"]),
|
|
10
|
+
{
|
|
11
|
+
files: ["**/*.{ts,tsx}"],
|
|
12
|
+
extends: [
|
|
13
|
+
js.configs.recommended,
|
|
14
|
+
tseslint.configs.recommended,
|
|
15
|
+
reactHooks.configs.flat.recommended,
|
|
16
|
+
reactRefresh.configs.vite,
|
|
17
|
+
],
|
|
18
|
+
languageOptions: {
|
|
19
|
+
globals: globals.browser,
|
|
20
|
+
},
|
|
21
|
+
rules: {
|
|
22
|
+
"@typescript-eslint/no-explicit-any": "off",
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
]);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
+
<title>template-vite-server — 现代 Web 应用模板</title>
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<div id="root"></div>
|
|
11
|
+
<script type="module" src="/src/main.tsx"></script>
|
|
12
|
+
</body>
|
|
13
|
+
</html>
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "__PROJECT_NAME__",
|
|
3
|
+
"private": true,
|
|
4
|
+
"version": "0.0.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "vite",
|
|
8
|
+
"build": "tsc -b && vite build",
|
|
9
|
+
"lint": "eslint .",
|
|
10
|
+
"preview": "vite preview"
|
|
11
|
+
},
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"@lightfish/react-model": "^0.0.1",
|
|
14
|
+
"@lightfish/router": "^0.0.1",
|
|
15
|
+
"@tailwindcss/vite": "^4.3.0",
|
|
16
|
+
"ahooks": "^3.9.7",
|
|
17
|
+
"react": "^19.2.6",
|
|
18
|
+
"react-dom": "^19.2.6",
|
|
19
|
+
"react-router-dom": "6.21.1",
|
|
20
|
+
"tailwindcss": "^4.3.0"
|
|
21
|
+
},
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"@eslint/js": "^10.0.1",
|
|
24
|
+
"@lightfish/server": "^0.0.24",
|
|
25
|
+
"@types/node": "^24.12.3",
|
|
26
|
+
"@types/react": "^19.2.14",
|
|
27
|
+
"@types/react-dom": "^19.2.3",
|
|
28
|
+
"@vitejs/plugin-react": "^6.0.1",
|
|
29
|
+
"code-inspector-plugin": "^1.5.1",
|
|
30
|
+
"drizzle-kit": "^0.31.10",
|
|
31
|
+
"drizzle-orm": "^0.45.2",
|
|
32
|
+
"eslint": "^10.3.0",
|
|
33
|
+
"eslint-plugin-react-hooks": "^7.1.1",
|
|
34
|
+
"eslint-plugin-react-refresh": "^0.5.2",
|
|
35
|
+
"globals": "^17.6.0",
|
|
36
|
+
"pg": "^8.22.0",
|
|
37
|
+
"typescript": "~6.0.2",
|
|
38
|
+
"typescript-eslint": "^8.59.2",
|
|
39
|
+
"vite": "^8.0.12"
|
|
40
|
+
}
|
|
41
|
+
}
|