Private
Public Access
1
0
Files
u-desk/docs/01-技术文档/CodeMirror/CodeMirror-经验教训.md

5.5 KiB
Raw Blame History

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 次成功)

对比正常工作的代码 → 发现差异 → 统一代码风格

  1. SqlEditor.vue - 使用 defaultHighlightStyle → 正常工作
  2. CodeEditor.vue - 使用自定义 HighlightStyle.define() → 报错

解决: 改用 defaultHighlightStyle,问题立即解决


🔍 失败原因分析

为什么会犯这个错误?

  1. 被错误信息误导

    • 错误信息提到 "multiple instances"
    • 就认为是依赖管理/构建配置问题
    • 实际上是自定义代码导致的问题
  2. 忽略了"奥卡姆剃刀原则"

    • 应该先检查最简单的解释
    • "为什么其他组件正常工作?"
    • "它们和我的代码有什么不同?"
  3. 过度依赖配置调整

    • 认为通过配置可以解决任何问题
    • 实际上问题在代码层面
    • 配置调整治标不治本

时间浪费统计

尝试次数 方向 耗时估计 结果
1-9 构建配置调整 ~4-5 小时 全部失败
10 对比正常代码 ~5 分钟 成功

浪费时间: 4-5 小时 正确方案: 5 分钟 比例: 48:1 - 60:1


正确的排查流程

应该这样做(下次)

第一步:对比法
├─ 找到正常工作的类似代码SqlEditor.vue
├─ 逐行对比,找出差异
└─ 统一代码风格和实现方式

第二步:确认问题范围
├─ 是全局问题?(所有编辑器都不工作) → 可能是配置问题
└─ 是局部问题?(某个组件不工作)   → 优先检查代码差异

第三步:从简单到复杂
├─ 先检查代码逻辑和导入
├─ 再检查配置文件
└─ 最后检查构建工具

不应该这样做

❌ 一看到错误信息就认为是构建问题
❌ 盲目调整各种配置选项
❌ 尝试复杂的解决方案
❌ 忽略正常工作的代码

📚 经验总结

技术层面

  1. 统一代码风格的重要性

    • 使用官方默认方案(defaultHighlightStyle
    • 避免自定义可能引入问题的实现
    • 团队成员使用相同的模式
  2. "能用"比"个性"更重要

    • 自定义语法高亮颜色 → 带来问题
    • 使用默认样式 → 稳定可靠
    • 如果需要自定义,优先用 CSS 覆盖
  3. 错误信息可能误导

    • "multiple instances" 不一定是依赖问题
    • 可能是代码使用了不同的实例
    • 需要结合上下文分析

方法论层面

  1. 对比优先

    • 先找到正常工作的代码
    • 对比找出差异
    • 统一实现方式
  2. 简单优先

    • 奥卡姆剃刀原则:最简单的解释往往是正确的
    • 先检查代码,再检查配置
    • 先检查局部,再检查全局
  3. 时间价值

    • 花 5 分钟对比 = 省下 4-5 小时
    • 盲目尝试 = 浪费时间
    • 系统化排查 > 随机尝试

🎓 可复用的原则

通用排查原则

  1. 二分法

    问题发生
    ├── 其他地方正常吗?
    │   ├── 是 → 检查我的代码与正常代码的差异
    │   └── 否 → 检查全局配置/环境
    
  2. 控制变量法

    只改变一个因素,观察结果
    - 用正常工作的代码替换 → 还报错吗?
    - 用默认实现替换自定义 → 还报错吗?
    
  3. 时间盒原则

    如果 30 分钟内没有进展 →
    - 停止当前方向
    - 重新评估假设
    - 尝试完全不同的方法
    

📝 行动清单

下次遇到类似问题

  • 第一时间找到正常工作的代码
  • 对比差异,记录下来
  • 尝试统一代码风格
  • 如果无效,再检查配置
  • 设置 30 分钟时间盒
  • 遇到阻碍时,重新评估假设

长期改进

  • 建立代码规范文档,规定统一的实现方式
  • Code Review 时检查是否使用官方推荐方案
  • 定期分享排查经验,避免重复踩坑
  • 建立"常见问题自查清单"

🔗 相关文档


💡 一句话总结

如果其他代码正常工作,不要怀疑工具和配置,先怀疑你的代码与众不同。


这个教训值 4-5 小时的时间成本,希望下次能 5 分钟解决问题。