trouble / 常见坑总览
这个目录是"红旗"的集中清单。开发遇到莫名错误时优先来这里翻一遍。
vjcad 是一个完整的 CAD 引擎,开发中会遇到一些 跨模块的"看起来无关但其实根因相同" 的问题。本目录把它们按"症状"分组:
| 症状 | 主页 |
|---|---|
启动时画布黑屏 / 实体没进图(Engine 未就绪) / cadView.onLoad 卡住 |
init-pitfalls.md |
| 切页面 / 卸载组件后内存涨 / 事件回调被反复触发 | event-leak.md |
EntityAdded 事件触发了好多次 / PolylineEnt 加点时机怪 |
command-event-timing.md |
| 文档 / 示例 / 源码命名不一致 / 接口签名对不上 | source-conflicts.md |
通用排查方法
1. 看引擎是否初始化完毕
console.log('cadView:', cadView);
console.log('Engine:', Engine);
console.log('pcanvas:', Engine.pcanvas); // onLoad 前为 null
console.log('mounted:', !!document.getElementById('map'));
Engine 是静态类,永远不是 undefined;Engine.currentDoc 在 onLoad 前也不是 undefined(懒建的孤儿文档),判断是否就绪看 Engine.pcanvas 是否非 null,否则去 init-pitfalls。
2. 看事件是否被绑了多次
const events = CadEventManager.getInstance();
console.log('监听数:', events.listenerCount(CadEvents.EntityAdded)); // CadEventManager 上没有 _listeners 字段
用公开的
listenerCount(event);如果某个事件在你 console.log 时已经 > 1,可能是useEffect/ 路由切换时没有off。
3. 看命令是否被注册多次
console.log('已注册:', CommandRegistry.items.map(i => i.name));
items 是 CommandDefinition[] 静态数组;regist 只 push 不去重,执行时 CommandRegistry.item(name) 取第一个同名定义(先注册者胜出),后注册的不生效;要替换须先 CommandRegistry.unregist(name)(每次只删第一个匹配,重复注册过的要循环到返回 false)。
4. 关键的"先 await 再用"
| 调用 | 必须先 |
|---|---|
Engine.xxx |
await cadView.onLoad() |
cadOverlay.addTo(map) |
await map.onLoad() |
extractTables() 等同步 WASM 调用 |
WASM 已初始化(await cadView.onLoad() 已完成);parseSvgToWebcad 等 async 方法内部会自动 await this.initWasm(),无需手动调 |
Engine.editor.executerWithOp(cmd) |
CommandRegistry.regist(cmdDef) |
Engine.patternManager.registerPattern |
Engine 已加载 |
5. 善用 writeMessage
vjcad 在底部命令行打字(HTML)一直是最快的"事件 / 状态"调试通道:
writeMessage('<br/>当前实体数: ' + Engine.currentSpace.items.length); // BlockDefinition 字段是 items/aliveItems,无 .entities
6. 仅 dev 时打开详细日志
if (import.meta.env.DEV) {
// 没有 CadEvents.AnyEvent 通配——要全量监听就自己枚举所有值
const handlers = {};
for (const t of Object.values(CadEvents)) {
handlers[t] = args => console.log('[CAD]', t, args);
Engine.eventManager.on(t, handlers[t]);
}
}
生产环境务必关掉这类全量监听。
参考(官方文档 MCP)
- 子页面分别引用了
vjcad/doc/event/*.md、vjcad/doc/guide/*.md,请按子页面查看 - 通用调试通道(
writeMessage、Engine.eventManager.on(CadEvents.XXX, ...))见vjcad/doc/event/event-usage.md