♻️ chore: refactor router runtime (#9306)

This commit is contained in:
YuTengjing
2025-09-17 23:30:04 +08:00
committed by GitHub
parent 2e928cd587
commit 1762dc9148
21 changed files with 240 additions and 151 deletions
+4 -4
View File
@@ -18,13 +18,13 @@ The project uses the following technologies:
- Next.js 15 for frontend and backend, using app router instead of pages router
- react 19, using hooks, functional components, react server components
- TypeScript programming language
- antd, @lobehub/ui for component framework
- antd, `@lobehub/ui` for component framework
- antd-style for css-in-js framework
- react-layout-kit for flex layout
- react-i18next for i18n
- lucide-react, @ant-design/icons for icons
- @lobehub/icons for AI provider/model logo icon
- @formkit/auto-animate for react list animation
- lucide-react, `@ant-design/icons` for icons
- `@lobehub/icons` for AI provider/model logo icon
- `@formkit/auto-animate` for react list animation
- zustand for global state management
- nuqs for type-safe search params state manager
- SWR for react data fetch
+2 -2
View File
@@ -86,9 +86,9 @@ const Card: FC<CardProps> = ({ title, content }) => {
## Lobe UI 包含的组件
- 不知道 @lobehub/ui 的组件怎么用,有哪些属性,就自己搜下这个项目其它地方怎么用的,不要瞎猜,大部分组件都是在 antd 的基础上扩展了属性
- 不知道 `@lobehub/ui` 的组件怎么用,有哪些属性,就自己搜下这个项目其它地方怎么用的,不要瞎猜,大部分组件都是在 antd 的基础上扩展了属性
- 具体用法不懂可以联网搜索,例如 ActionIcon 就爬取 https://ui.lobehub.com/components/action-icon
- 可以阅读 node_modules/@lobehub/ui/es/index.js 了解有哪些组件,每个组件的属性是什么
- 可以阅读 `node_modules/@lobehub/ui/es/index.js` 了解有哪些组件,每个组件的属性是什么
- General
- ActionIcon
+57 -5
View File
@@ -8,11 +8,63 @@ alwaysApply: false
## Types and Type Safety
- Avoid explicit type annotations when TypeScript can infer types.
- Avoid implicitly `any` variables; explicitly type when necessary (e.g., `let a: number` instead of `let a`).
- Use the most accurate type possible (e.g., prefer `Record<PropertyKey, unknown>` over `object`).
- Prefer `interface` over `type` for object shapes (e.g., React component props). Keep `type` for unions, intersections, and utility types.
- Prefer `as const satisfies XyzInterface` over plain `as const` when suitable.
- avoid explicit type annotations when TypeScript can infer types.
- avoid implicitly `any` variables; explicitly type when necessary (e.g., `let a: number` instead of `let a`).
- use the most accurate type possible (e.g., prefer `Record<PropertyKey, unknown>` over `object`).
- prefer `interface` over `type` for object shapes (e.g., React component props). Keep `type` for unions, intersections, and utility types.
- prefer `as const satisfies XyzInterface` over plain `as const` when suitable.
- prefer `@ts-expect-error` over `@ts-ignore`
- prefer `Record<string, any>` over `any`
- **Avoid unnecessary null checks**: Before adding `xxx !== null`, `?.`, `??`, or `!.`, read the type definition to confirm the necessary. **Example:**
```typescript
// ❌ Wrong: budget.spend and budget.maxBudget is number, not number | null
if (budget.spend !== null && budget.maxBudget !== null && budget.spend >= budget.maxBudget) {
// ...
}
// ✅ Right
if (budget.spend >= budget.maxBudget) {
// ...
}
```
- **Avoid redundant runtime checks**: Don't add runtime validation for conditions already guaranteed by types or previous checks. Trust the type system and calling contract. **Example:**
```typescript
// ❌ Wrong: Adding impossible-to-fail checks
const due = await db.query.budgets.findMany({
where: and(isNotNull(budgets.budgetDuration)), // Already filtered non-null
});
const result = due.map(b => {
const nextReset = computeNextResetAt(b.budgetResetAt!, b.budgetDuration!);
if (!nextReset) { // This check is impossible to fail
throw new Error(`Unexpected null nextResetAt`);
}
return nextReset;
});
// ✅ Right: Trust the contract
const due = await db.query.budgets.findMany({
where: and(isNotNull(budgets.budgetDuration)),
});
const result = due.map(b => computeNextResetAt(b.budgetResetAt!, b.budgetDuration!));
```
- **Avoid meaningless null/undefined parameters**: Don't accept null/undefined for parameters that have no business meaning when null. Design strict function contracts. **Example:**
```typescript
// ❌ Wrong: Function accepts meaningless null input
function computeNextResetAt(currentResetAt: Date, durationStr: string | null): Date | null {
if (!durationStr) return null; // Why accept null if it just returns null?
}
// ✅ Right: Strict contract, clear responsibility
function computeNextResetAt(currentResetAt: Date, durationStr: string): Date {
// Function has single clear purpose, caller ensures valid input
}
```
## Imports and Modules