5.5 KiB
5.5 KiB
CodeMirror 问题排查经验教训
日期: 2026-02-05 问题: CodeMirror 多实例错误 探索次数: 10 次 最终解决时间: 5 分钟
🎯 核心教训
当遇到问题时,应该先对比正常工作的代码,而不是盲目调整构建配置。统一的代码风格(使用官方默认方案)往往能避免很多问题。
📊 问题回顾
错误信息
Error: Unrecognized extension value in extension set ([object Object]).
This sometimes happens because multiple instances of @codemirror/state are loaded,
breaking instanceof checks.
错误假设(导致 9 次失败)
看到错误提示 "multiple instances of @codemirror/state",就认为是构建配置问题:
- Vite 预构建导致多实例
- 需要配置 resolve.alias 强制单实例
- 需要配置 dedupe 去重
- 需要移除 manualChunks 避免代码分割
- ...
结果: 尝试了 9 种构建配置方案,全部失败 ❌
正确思路(10 次成功)
对比正常工作的代码 → 发现差异 → 统一代码风格
- SqlEditor.vue - 使用
defaultHighlightStyle→ 正常工作 ✅ - CodeEditor.vue - 使用自定义
HighlightStyle.define()→ 报错 ❌
解决: 改用 defaultHighlightStyle,问题立即解决 ✅
🔍 失败原因分析
为什么会犯这个错误?
-
被错误信息误导
- 错误信息提到 "multiple instances"
- 就认为是依赖管理/构建配置问题
- 实际上是自定义代码导致的问题
-
忽略了"奥卡姆剃刀原则"
- 应该先检查最简单的解释
- "为什么其他组件正常工作?"
- "它们和我的代码有什么不同?"
-
过度依赖配置调整
- 认为通过配置可以解决任何问题
- 实际上问题在代码层面
- 配置调整治标不治本
时间浪费统计
| 尝试次数 | 方向 | 耗时估计 | 结果 |
|---|---|---|---|
| 1-9 | 构建配置调整 | ~4-5 小时 | 全部失败 ❌ |
| 10 | 对比正常代码 | ~5 分钟 | 成功 ✅ |
浪费时间: 4-5 小时 正确方案: 5 分钟 比例: 48:1 - 60:1
✅ 正确的排查流程
应该这样做(下次)
第一步:对比法
├─ 找到正常工作的类似代码(SqlEditor.vue)
├─ 逐行对比,找出差异
└─ 统一代码风格和实现方式
第二步:确认问题范围
├─ 是全局问题?(所有编辑器都不工作) → 可能是配置问题
└─ 是局部问题?(某个组件不工作) → 优先检查代码差异
第三步:从简单到复杂
├─ 先检查代码逻辑和导入
├─ 再检查配置文件
└─ 最后检查构建工具
不应该这样做
❌ 一看到错误信息就认为是构建问题
❌ 盲目调整各种配置选项
❌ 尝试复杂的解决方案
❌ 忽略正常工作的代码
📚 经验总结
技术层面
-
统一代码风格的重要性
- 使用官方默认方案(
defaultHighlightStyle) - 避免自定义可能引入问题的实现
- 团队成员使用相同的模式
- 使用官方默认方案(
-
"能用"比"个性"更重要
- 自定义语法高亮颜色 → 带来问题
- 使用默认样式 → 稳定可靠
- 如果需要自定义,优先用 CSS 覆盖
-
错误信息可能误导
- "multiple instances" 不一定是依赖问题
- 可能是代码使用了不同的实例
- 需要结合上下文分析
方法论层面
-
对比优先
- 先找到正常工作的代码
- 对比找出差异
- 统一实现方式
-
简单优先
- 奥卡姆剃刀原则:最简单的解释往往是正确的
- 先检查代码,再检查配置
- 先检查局部,再检查全局
-
时间价值
- 花 5 分钟对比 = 省下 4-5 小时
- 盲目尝试 = 浪费时间
- 系统化排查 > 随机尝试
🎓 可复用的原则
通用排查原则
-
二分法
问题发生 ├── 其他地方正常吗? │ ├── 是 → 检查我的代码与正常代码的差异 │ └── 否 → 检查全局配置/环境 -
控制变量法
只改变一个因素,观察结果 - 用正常工作的代码替换 → 还报错吗? - 用默认实现替换自定义 → 还报错吗? -
时间盒原则
如果 30 分钟内没有进展 → - 停止当前方向 - 重新评估假设 - 尝试完全不同的方法
📝 行动清单
下次遇到类似问题
- 第一时间找到正常工作的代码
- 对比差异,记录下来
- 尝试统一代码风格
- 如果无效,再检查配置
- 设置 30 分钟时间盒
- 遇到阻碍时,重新评估假设
长期改进
- 建立代码规范文档,规定统一的实现方式
- Code Review 时检查是否使用官方推荐方案
- 定期分享排查经验,避免重复踩坑
- 建立"常见问题自查清单"
🔗 相关文档
- CodeMirror 多实例问题修复记录 - 完整探索过程
- CodeMirror 修复状态报告 - 解决方案
- CodeMirror 配置优化总结 - 优化效果
💡 一句话总结
如果其他代码正常工作,不要怀疑工具和配置,先怀疑你的代码与众不同。
这个教训值 4-5 小时的时间成本,希望下次能 5 分钟解决问题。