205 lines
5.4 KiB
Markdown
205 lines
5.4 KiB
Markdown
# AGENTS.md
|
||
|
||
## 构建、代码检查和测试命令
|
||
|
||
### 核心命令
|
||
|
||
```bash
|
||
# 开发
|
||
bun run dev # 运行主入口 (src/run.ts)
|
||
bun run dev:server # 启动服务器(热重载)
|
||
bun run dev:cnb # 使用自定义配置目录启动服务器
|
||
bun run dev:share # 测试远程应用
|
||
|
||
# 构建
|
||
bun run build # 完整生产构建(先清理 dist)
|
||
bun run build:lib # 构建库文件
|
||
bun run postbuild:lib # 生成 TypeScript 类型定义
|
||
|
||
# 包管理
|
||
pnpm install # 安装依赖(使用 pnpm v10.28.0)
|
||
```
|
||
|
||
### 环境要求
|
||
|
||
- **Node.js**: >=22.0.0
|
||
- **运行时**: Bun(开发环境)/ Node.js(生产环境)
|
||
- **包管理器**: pnpm@10.28.0(强制要求)
|
||
|
||
### 环境变量
|
||
|
||
- `ASSISTANT_CONFIG_DIR`: 覆盖助手配置文件目录路径
|
||
- `BUN_PATH`: 覆盖 Bun 可执行文件路径
|
||
|
||
---
|
||
|
||
## 代码风格规范
|
||
|
||
### TypeScript
|
||
|
||
- **严格模式**: 通过扩展配置启用(`@kevisual/types/json/backend.json`)
|
||
- **模块格式**: 仅 ESM(`package.json` 中的 `"type": "module"`)
|
||
- **目标**: NodeNext 模块解析
|
||
- **路径别名**: 使用 `@/*` 作为本地导入别名(如 `import { Foo } from '@/module/foo'`)
|
||
|
||
### 导入规则
|
||
|
||
```typescript
|
||
// Node.js 内置模块必须使用 node: 协议
|
||
import fs from 'node:fs';
|
||
import path from 'node:path';
|
||
import { execSync } from 'node:child_process';
|
||
|
||
// 外部包(不使用路径别名)
|
||
import chalk from 'chalk';
|
||
import { program } from 'commander';
|
||
|
||
// 本地模块(使用 @ 别名)
|
||
import { AssistantInit } from '@/services/init/index.ts';
|
||
|
||
// 类型导入
|
||
import type { AssistantConfig } from '@/module/assistant/index.ts';
|
||
```
|
||
|
||
### 命名规范
|
||
|
||
| 类型 | 规范 | 示例 |
|
||
|------|------|------|
|
||
| 类 | PascalCase | `AssistantInit`, `AssistantApp`, `AssistantQuery` |
|
||
| 接口 | PascalCase | `ProxyInfo`, `AssistantInitOptions` |
|
||
| 类型 | PascalCase | `AssistantConfigData` |
|
||
| 函数 | camelCase | `getBunPath`, `checkFileExists`, `parseHomeArg` |
|
||
| 变量 | camelCase | `configDir`, `assistantConfig`, `isPortAvailable` |
|
||
| 私有字段 | `#` 前缀 + camelCase | `#query`, `#config` |
|
||
| 常量 | UPPER_SNAKE_CASE 或 camelCase | `commonPaths`, `randomId` |
|
||
| 文件名 | kebab-case | `proxy-page-index.ts`, `query-login.ts` |
|
||
| 目录名 | kebab-case | `query-login`, `hot-api` |
|
||
|
||
### 代码模式
|
||
|
||
#### 错误处理
|
||
|
||
```typescript
|
||
// 同步操作包装
|
||
try {
|
||
const result = fs.readFileSync(path);
|
||
return result;
|
||
} catch (error) {
|
||
console.error('读取文件错误:', error.message);
|
||
continue; // 或 return/throw
|
||
}
|
||
|
||
// 异步操作包装
|
||
try {
|
||
const result = await someAsyncOperation();
|
||
return result;
|
||
} catch (error) {
|
||
console.error('操作失败:', error.message);
|
||
process.exit(1); // 或 throw/return undefined
|
||
}
|
||
```
|
||
|
||
#### 上下文/依赖注入
|
||
|
||
使用 `@kevisual/use-config` 进行上下文管理:
|
||
|
||
```typescript
|
||
export const assistantConfig = useContextKey<AssistantInit>('assistantConfig', () => {
|
||
return new AssistantInit({
|
||
path: configDir,
|
||
init: isInit,
|
||
});
|
||
});
|
||
```
|
||
|
||
#### 路由模式
|
||
|
||
使用 `@kevisual/router` 的 App 和 SimpleRouter:
|
||
|
||
```typescript
|
||
app.route({
|
||
path: 'router',
|
||
key: 'list',
|
||
description: '获取路由列表',
|
||
}).define(async (ctx) => {
|
||
ctx.body = { list };
|
||
}).addTo(app);
|
||
```
|
||
|
||
### JSDoc 文档
|
||
|
||
为公共 API、复杂函数和类型添加文档:
|
||
|
||
```typescript
|
||
/**
|
||
* 助手初始化类
|
||
* @class AssistantInit
|
||
*/
|
||
export class AssistantInit extends AssistantConfig {}
|
||
|
||
/**
|
||
* @param {string} p - 要解析的路径
|
||
* @returns {string} 解析后的绝对路径
|
||
*/
|
||
export const w = (p: string) => path.join(__dirname, p);
|
||
```
|
||
|
||
### 文件组织
|
||
|
||
- **路由**: `src/routes/` 和 `src/routes-simple/`
|
||
- **模块**: `src/module/`(功能模块)
|
||
- **服务**: `src/services/`(公共服务)
|
||
- **命令**: `src/command/`(CLI 命令)
|
||
- **查询**: `src/query/`(API/查询逻辑)
|
||
- **入口文件**:
|
||
- `src/index.ts` - 主 CLI 入口
|
||
- `src/server.ts` - 服务器入口
|
||
- `src/run.ts` - 开发运行器
|
||
- `src/run-server.ts` - 服务器运行器
|
||
|
||
### 控制台输出
|
||
|
||
使用 `chalk` 实现彩色输出:
|
||
|
||
```typescript
|
||
console.log(chalk.blue('助手路径不存在,正在创建...'));
|
||
console.log(chalk.yellow('助手路径已存在'), chalk.green(assistantConfig.configDir));
|
||
console.error(chalk.red('启动服务器错误:'), error.message);
|
||
```
|
||
|
||
### 系统检测
|
||
|
||
```typescript
|
||
const isWindows = process.platform === 'win32';
|
||
const bunExecutableName = isWindows ? 'bun.exe' : 'bun';
|
||
```
|
||
|
||
### 端口处理
|
||
|
||
```typescript
|
||
import getPort, { portNumbers } from 'get-port';
|
||
|
||
const port = await getPort({ port: 51515 });
|
||
const availablePort = await getPort({ port: portNumbers(51515, 52000) });
|
||
```
|
||
|
||
### 关键依赖
|
||
|
||
- `@kevisual/router` - 应用路由
|
||
- `@kevisual/query` - API 查询
|
||
- `@kevisual/use-config` - 配置/上下文
|
||
- `commander` - CLI 参数解析
|
||
- `chalk` - 终端颜色
|
||
- `ws` - WebSocket(通过 `@kevisual/ws`)
|
||
- `pm2` - 进程管理(生产环境)
|
||
|
||
### 重要说明
|
||
|
||
1. 开发时始终使用 `bun`,但构建输出以 Node.js 为目标
|
||
2. 打包时外部包必须在 `bun.config.mjs` 的 `external` 数组中声明
|
||
3. 库构建排除 `pm2`
|
||
4. 以 `ENVISION_*` 为前缀的环境变量在构建时可用
|
||
5. 项目在业务逻辑中广泛使用中文注释
|
||
6. 私有类成员应使用 `#` 前缀语法
|
||
7. 操作前始终使用 `checkFileExists` 检查文件是否存在
|