时间: 2026-05-19 ~ 2026-05-25
版本: 未发版
变更: 833 个文件, +15,963(新增) / -82,608(删除) 行
这周是重构力度最大的一周。净删了将近七万行代码——不是功能少了,是把一个单体前端拆成了四个独立 app。
多应用架构
apps/frontend/ ——那个包含了所有页面、所有逻辑的大一统项目——被彻底拆了:
graph TD
subgraph "旧: apps/frontend/ (单体, ~82,000行)"
O_FE[所有页面在一个项目里<br/>editor + home + viewport + designer]
end
subgraph "新: 四个独立 SPA"
EDITOR[<b>apps/editor</b><br/>工作区编辑器<br/>React 19 + Vite 8<br/>React Compiler]
HOME[<b>apps/home</b><br/>登录/仪表板<br/>React 19 + Vite 7<br/>TanStack Router]
VIEWPORT[<b>apps/viewport</b><br/>3D 视口查看器<br/>React 19 + Vite 7<br/>Three.js]
DESIGNER[<b>apps/designer</b><br/>主题/图设计器<br/>React 19 + Vite 7<br/>ncf-editor]
end
subgraph "共享 Packages"
UI[packages/ui<br/>35 shadcn 组件]
SHARED[packages/shared<br/>IPC/存储/视口设置]
NCF[packages/ncf-editor<br/>流程图编辑器]
API[packages/api<br/>共享 TS 类型库]
DESKTOP[packages/desktop<br/>Electron 壳]
end
O_FE ==> EDITOR
O_FE ==> HOME
O_FE ==> VIEWPORT
O_FE ==> DESIGNER
EDITOR -.-> UI
EDITOR -.-> SHARED
EDITOR -.-> NCF
HOME -.-> UI
HOME -.-> SHARED
VIEWPORT -.-> UI
VIEWPORT -.-> NCF
DESIGNER -.-> UI
DESIGNER -.-> NCF
每个 app 有自己的 Vite 配置、路由、入口点。改一个 app 不影响其他 app 的构建。
Desktop 多窗口
旧 Electron 是单窗口模型。新的多窗口架构:
sequenceDiagram
participant Home as Home 窗口<br/>(启动器 1120x630)
participant Main as Electron Main Process
participant Editor as Editor 窗口<br/>(编辑器 1280x720)
participant VP as Viewport 窗口<br/>(3D 视口 800x450)
participant Space as esws.exe (Space)
Home->>Main: IPC: open-editor(root)
Main->>Main: spawn esws.exe, 获取 port+key
Main->>Editor: 创建窗口, URL?port=xxx&key=xxx
Home->>Home: 隐藏自己
Editor->>Space: SignalR 连接 + Load
Editor->>Main: IPC: open-viewport
Main->>VP: 创建 Viewport 窗口
VP->>Main: IPC: signalr-rpc:forward
Main->>Editor: IPC 转发 RPC 调用
Editor->>Main: IPC: close-workspace
Main->>Home: IPC: close-workspace-confirmed
Home->>Home: 显示自己
Main->>Space: 关闭 esws 进程
窗口间通过 IPC 通信,不直接调函数。esws.ts 管理后端子进程生命周期。
五个 God Object 分尸
旧编辑器里有五个单文件怪物,这周全拆了:
graph LR
subgraph "拆分前 (5 个文件, 3,173行)"
G1[workspace.ts<br/>263行]
G2[tabs/store.ts<br/>569行]
G3[file-tree/store.ts<br/>777行]
G4[signalr.ts<br/>727行]
G5[ncf/editor.tsx<br/>837行]
end
subgraph "拆分后 (39 个文件)"
W1[workspace/<br/>10文件]
W2[tabs/store/<br/>8文件]
W3[file-tree/store/<br/>7文件]
W4[signalr/<br/>8文件]
W5[ncf/editor/<br/>6文件]
end
G1 ==> W1
G2 ==> W2
G3 ==> W3
G4 ==> W4
G5 ==> W5
拆分后的结构示例(以 stores/workspace/ 为例):
stores/workspace/
types.ts # 类型定义
index.ts # Zustand store 组合
graph-actions.ts # 图操作
execution.ts # 执行状态
session-events.ts # 会话生命周期
breakpoints.ts # 断点管理
syntax-errors.ts # 语法错误
favorites.ts # 收藏夹
file-ops.ts # 文件操作
flow-service.ts # FlowService 类 (97行)
拆完后的感受:一个文件超过 300 行就该警觉,超过 500 行就是技术债。
统一存储抽象
graph TD
subgraph "存储层架构"
API_STORE["Storage API"] --> SCOPE_G["全局作用域\ne3.global.{key}"]
API_STORE --> SCOPE_W["工作区作用域\ne3.wk.{hash8}.{key}"]
SCOPE_G --> ELEC["Electron\nIPC → 主进程 JSON"]
SCOPE_G --> WEB["Web\nlocalStorage"]
SCOPE_W --> ELEC
SCOPE_W --> WEB
ELEC --> SYNC["storage-change IPC\n跨窗口同步"]
end
packages/shared/src/storage.ts(239 行)——三个作用域,双后端,跨窗口同步。
测试补课
加了 35 个测试文件,283 个测试。覆盖了 Models、Host、DSL、Extensions、Space、Integration。
日志系统
graph LR
LOG["createLogger(module)"] --> L1["log: 蓝色\n仅 dev"]
LOG --> L2["warn: 黄色\n始终"]
LOG --> L3["error: 红色\n始终"]
LOG --> L4["debug: 紫色\ndev 或 e3_debug=1"]
L1 --> PREFIX["[moduleName] 前缀"]
L2 --> PREFIX
L3 --> PREFIX
L4 --> PREFIX
这周删了八万行、加了一万六千行,净减六万多。最健康的代码是已删除的代码。拆 app、分 god object、统一共享包——每一步都在减少复杂度。