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

212 lines
5.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 时检查是否使用官方推荐方案
- [ ] 定期分享排查经验,避免重复踩坑
- [ ] 建立"常见问题自查清单"
---
## 🔗 相关文档
- [CodeMirror 多实例问题修复记录](./CodeMirror-多实例问题修复记录.md) - 完整探索过程
- [CodeMirror 修复状态报告](./CodeMirror-修复状态报告.md) - 解决方案
- [CodeMirror 配置优化总结](./CodeMirror-配置优化总结.md) - 优化效果
---
## 💡 一句话总结
> **如果其他代码正常工作,不要怀疑工具和配置,先怀疑你的代码与众不同。**
---
**这个教训值 4-5 小时的时间成本,希望下次能 5 分钟解决问题。**