oh-my-muse/docs/memorys/2026-05-24-muse-studio脚手架与基础设施搭建.md
zizi 317dfd4d13 feat(muse-studio): 搭建 P2 用户端工作台
完成 Muse Studio React SPA 基座和六个用户端功能域,接入 MSW Mock、Tiptap 写作台、知识库资料管理、智能体槽位预检绑定、市场授权安装和个人中心用量权益视图。
2026-05-25 10:15:28 +08:00

77 lines
3.2 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.

# muse-studio 脚手架与核心基础设施搭建留痕
## 任务背景
在根目录从零初始化前端用户端子项目 `muse-studio`Vite + React + TS 结构并完成路由、统一客户端、MSW 2.0 Mock、IndexedDB 及 Zustand 状态库等基础设施建设。
## 关键工程实践与避坑指南
### 1. TypeScript 6.0 严格模式兼容
#### (1) `erasableSyntaxOnly` 限制
- **现象**当启用该规则时TypeScript 6.0 禁用了 parameter properties 语法(如在 constructor 参数中直接写 `public code: string`)。
- **避坑**:声明异常类或常规类时,需采用标准 ES ES6 属性定义:
```typescript
export class ApiError extends Error {
public code: string;
public status: number;
constructor(code: string, message: string, status: number) {
super(message);
this.code = code;
this.status = status;
}
}
```
#### (2) `exactOptionalPropertyTypes` 限制
- **现象**:在对象字面量中如果显式将可选属性设为 `undefined` 会报错。
- **避坑**:构造请求参数(如 RequestInit 的 `body`)时,避免传入 `body: undefined`。应采用动态属性扩展或先判断再赋值:
```typescript
const options: RequestInit = { method: 'POST' };
if (data !== undefined) {
options.body = JSON.stringify(data);
}
```
#### (3) `baseUrl` 被废弃
- **现象**TypeScript 6.0+ 将逐渐废弃 `baseUrl`,编译时会报 TS5101 错误。
- **避坑**:从 `tsconfig.app.json` 中直接移除 `"baseUrl"`Vite + TS 依然能够通过相对位置正确解析 `"paths"`(别名映射)。
### 2. pnpm 包管理构建脚本受阻
- **现象**:在新版 pnpm (v10/v11) 中,若存在未显式授权的构建脚本(如 `esbuild`, `msw`),任何 pnpm 命令在运行依赖完整性检查时都会抛出 `[ERR_PNPM_IGNORED_BUILDS]` 并强制中断。
- **解决方案**
1. **本地开发**:在子项目根目录下创建 `.npmrc` 并添加以下白名单配置:
```ini
only-built-dependencies[]=esbuild
only-built-dependencies[]=msw
```
2. **CI 或自动化编译**:如果依然受到全局白名单阻碍,可使用 `--ignore-scripts` 绕过依赖构建脚本检查:
```bash
pnpm install --ignore-scripts
```
### 3. MSW 2.0 模拟 SSE (Server-Sent Events)
- **实现**MSW 2.0 支持使用 `ReadableStream` 模拟 SSE 流式推送。在 Mock 处理器中可通过 `TextEncoder` 写入符合 EventSource 格式的缓冲行,并在 headers 中指定 `text/event-stream`。
```typescript
http.get('/api/ai/stream', () => {
const encoder = new TextEncoder();
const stream = new ReadableStream({
async start(controller) {
controller.enqueue(encoder.encode(`data: ${JSON.stringify({ type: 'chunk', content: '数据' })}\n\n`));
controller.close();
}
});
return new HttpResponse(stream, {
headers: { 'Content-Type': 'text/event-stream' }
});
})
```
### 4. Zustand 4 严格模式类型推断
- **避坑**:在 Zustand Store 中,为了避免隐式 `any` 类型报错,建议统一使用柯里化方法传入泛型定义:
```typescript
import create from 'zustand';
export const useUIStore = create<UIState>()((set) => ({ ... }));
```