保留一个可复现的最小文件
问题报告应包含原始 Markdown、安装扩展及配置、模式/只读状态、复现步骤和版本。不要只截取渲染后的 HTML:源码拼写、围栏是否闭合以及选区位置都可能决定行为。
先保留未保存源码,再缩减扩展组合;同一 UI 问题可以暂时切换 source 模式判断文本是否仍正确。不要通过重新创建实例“修复”问题并丢掉撤销历史。
常见问题定位
| 现象 | 先检查 |
|---|---|
| 插件语法原样显示 | 是否安装、是否闭合、类型名是否注册、解析是否 pending |
| 自定义节点显示但不能改 | 字段验证、patch 是否实现、只读、原范围是否过期 |
| 组件不出现 | 是否使用对应 renderer,Host 是否仍在 Provider 树里 |
| 自定义代码块只有工具栏 | CodeBlock NodeView 本来只控制 header;整块预览需要 block 层 |
| 双份组件或重复安装错误 | 是否同时安装 StarterKit 的原功能和同名派生功能 |
| 切换语言后仍不高亮 | codeLanguages 是否包含精确名称/别名,加载是否失败 |
| 图表空白 | 容器尺寸、数据校验、引擎错误及加载状态 |
| 中文输入中光标跳动 | 是否在 composition 中改 DOM、抢焦点或重建 editor |
| 弹窗确认改错位置 | 是否丢失 target,或使用了旧数值偏移 |
| 只读仍有替换入口 | 控件是否读取实际 readOnly,最终是否检查命令结果 |
观察错误与语义
ts
const options = {
onError(error: unknown) { console.error('MSFE integration error', error) },
}
const query = editor.querySource('customContainer')
const outcome = editor.lastCommandResult
const work = editor.work
由宿主把 onError 接到开发诊断和产品错误边界。不要把文档正文、凭证或整个 editor 对象直接发送到外部日志服务。命令拒绝通常是可处理结果,并不都会作为异常抛出。
querySource 的 pending 和 unsupported 需要分别处理。工作计数适合比较同一动作前后的差值,不能把累计值当作渲染耗时;替换冲突检查 projectionConflicts。
自定义功能最低验证矩阵
| 方面 | 验证动作 | 必须成立 |
|---|---|---|
| 源码 | 原样加载、模式切换、显示预览 | 未发写命令时逐字不变 |
| 写回 | 改字段、撤销、重做 | 只改声明的范围,恢复原拼写 |
| 输入 | 中文组合、删除半个 token、粘贴 | 不抢输入,未完成语法保持源码 |
| 选区 | 点击、键盘、拖过预览、搜索 | 命中正确源码,拖动过程连续 |
| 权限 | source/live 只读、locked | 不能通过组件绕过写保护 |
| 生命周期 | 快速更新、卸载、换文档 | 没有迟到结果和资源泄漏 |
| 视觉 | 深浅色、窄屏、放大文字 | 使用主题 token,控件可达 |
| 性能 | 光标移动、局部改字、长文件 | 不做无关全文扫描或全量重挂载 |
文档示例如何作为起点
本网站的接入源码与交互示例来自同一组文件,发布时验证依赖闭包,并对 Vue / TypeScript 示例执行类型检查。带服务端端点的 recipe 明确要求宿主实现服务,不会伪造一个成功的后端。
复制示例后,先运行其说明中的验收动作,再增加业务字段和外部请求。遇到能力边界请对照 支持范围,不要为获得一张正确截图而关闭源码、选区或只读保护。