Private
Public Access
1
0
Files
u-desk/docs/01-技术文档/CodeMirror/CodeMirror-修复状态报告.md

214 lines
6.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
**状态**: ✅ 已修复
---
## 🎉 修复成功
经过 10 次探索,**问题已成功解决**
**最终方案**: 统一使用 `defaultHighlightStyle`,移除自定义高亮样式
---
## 📊 问题摘要
**错误**: `Unrecognized extension value in extension set` - CodeMirror 6 多实例错误
**影响**: 代码编辑器无法加载,语法高亮失效
---
## 🔧 已尝试的解决方案
| # | 方案 | 结果 | 详情 |
|---|------|------|------|
| 1 | 统一导出文件 | ❌ | codemirrorExports.js |
| 2 | manualChunks 合并 | ❌ | 反而可能导致问题 |
| 3 | 移除旧包 | ❌ | 版本不是问题 |
| 4 | 修复返回格式 | ❌ | 不是根本原因 |
| 5 | resolve.alias | ❌ | Windows 路径问题 |
| 6 | dedupe + exclude | ❌ | 主要影响开发模式 |
| 7 | 移除 manualChunks | ❌ | 即使单文件打包仍失败 |
| 8 | 深入分析错误 | ✅ | 找到真正原因 |
| 9 | **统一使用默认样式** | ✅ | **成功** |
---
## ✅ 最终解决方案
### 方案:使用 `defaultHighlightStyle`
**文件修改**:
1. **CodeEditor.vue** (frontend/src/components/CodeEditor.vue)
- 移除 `HighlightStyle``tags` 导入
- 添加 `defaultHighlightStyle``syntaxHighlighting` 导入
- 删除 `lightHighlightStyle` 定义22 行代码)
- 修改 `getThemeExtension()` 使用 `syntaxHighlighting(defaultHighlightStyle)`
2. **codemirrorExports.js** (frontend/src/utils/codemirrorExports.js)
- 移除 `HighlightStyle``tags` 的导出
### 验证结果
- ✅ 生产环境构建成功(无错误)
- ✅ 开发服务器启动成功
- ✅ 与 SqlEditor 等其他组件保持一致
### vite.config.js
```javascript
export default defineConfig({
resolve: {
alias: { '@': resolve(__dirname, 'src') },
// 强制去重 CodeMirror 包
dedupe: [
'@codemirror/state',
'@codemirror/view',
'@codemirror/language',
// ... 所有 CodeMirror 和 Lezer 包
]
},
build: {
rollupOptions: {
output: {
// 移除 manualChunks让 Rollup 自动处理
chunkFileNames: 'assets/js/[name]-[hash].js',
entryFileNames: 'assets/js/[name]-[hash].js',
assetFileNames: 'assets/[ext]/[name]-[hash].[ext]'
}
}
},
optimizeDeps: {
include: ['vue', 'pinia', '@arco-design/web-vue', 'marked', 'highlight.js'],
// 排除 CodeMirror避免预构建多实例
exclude: [
'@codemirror/state',
// ... 所有 CodeMirror 包
]
}
})
```
### 构建结果
- **主包**: `index-CB_oYaZz.js` (2.5 MB) - 包含所有代码
- **无单独的 CodeMirror chunk** - 所有 CodeMirror 代码在同一 bundle 中
---
## 📝 技术原理
### 真正原因
**之前的假设**: 多个 `@codemirror/state` 实例导致 instanceof 检查失败
**实际原因**: `HighlightStyle.define()` 创建的扩展对象与 `defaultHighlightStyle` 使用了不同的 `@lezer/highlight` 实例
### 为什么之前的方案都失败了
1. **统一导出文件** - 无法解决预构建阶段的多实例
2. **manualChunks 合并** - 即使打包到单个文件仍失败
3. **resolve.alias** - Windows 路径问题,且不能解决 `@lezer/highlight` 实例问题
4. **移除 manualChunks** - 代码在同一 bundle 中,但 `HighlightStyle.define()` 内部使用了不同的实例
### 为什么最终方案成功
- **SqlEditor.vue** 使用 `defaultHighlightStyle` 一直正常工作
- **CodeEditor.vue** 改用 `defaultHighlightStyle` 后也正常了
- 官方提供的 `defaultHighlightStyle` 内部处理了实例一致性问题
---
## 📝 关于自定义样式
**问题**: 自定义样式不能用吗?
**答案**: 可以用,但需要确保实例一致性。
### 方案 1使用 CSS 覆盖(推荐)
基于默认高亮样式,通过 CSS 修改颜色:
```css
/* 在组件的 <style> 中 */
.cm-editor :deep(.cm-keyword) { color: #d73a49 !important; }
.cm-editor :deep(.cm-string) { color: #032f62 !important; }
```
### 方案 2确保 tags 实例统一
所有地方都从同一个 `@lezer/highlight` 导入 `tags`,确保没有多个实例。但这仍然可能失败。
**当前方案**选择了最简单、最稳定的方案:使用官方默认样式。
---
## 📚 相关文档
- [完整探索记录](./CodeMirror-多实例问题修复记录.md) - 10 次探索的完整过程
- [CodeMirror 官方讨论 #5174](https://discuss.codemirror.net/t/error-multiple-instances-of-codemirror-state-v6/5174)
- [Vite 构建优化文档](https://vitejs.dev/guide/build.html)
---
## 🎯 关键发现
**问题本质**: 自定义 `HighlightStyle.define()` 创建的对象与默认样式使用的 `@lezer/highlight` 实例不一致。
**根本原因**: `tags` 实例的引用不一致,导致 instanceof 检查失败。
**解决方向**: 统一使用官方提供的 `defaultHighlightStyle`,避免自定义样式带来的实例问题。
---
## 📝 经验总结
### ❌ 错误方向
1. **关注构建配置** - resolve.alias、manualChunks、optimizeDeps 都无法解决
2. **代码分割问题** - 即使打包到单个文件仍然失败
3. **多实例问题** - @codemirror/state 实例不是根本原因
### ✅ 正确方向
1. **关注代码本身** - 自定义 `HighlightStyle.define()` 的问题
2. **对比正常工作的代码** - SqlEditor 使用默认样式正常工作
3. **使用官方方案** - `defaultHighlightStyle` 处理了实例一致性
### 核心教训
> **Occam's Razor奥卡姆剃刀原则**: 如果其他组件SqlEditor使用默认样式正常工作那么最简单的方案就是让 CodeEditor 也使用默认样式。
不应该花费 9 次尝试去调整构建配置,而应该第 1 次就对比正常工作的代码。
---
**修复完成!代码编辑器现在可以正常工作了。**
---
## 🚀 配置优化2026-02-05
在修复问题后,对构建配置进行了优化:
### 移除的无用配置
1. **resolve.dedupe** - 28 个包的去重配置,对生产构建无效
2. **optimizeDeps.exclude** - 28 个包的排除配置,不能解决 instanceof 问题
3. **inlineDynamicImports** - 导致所有代码打包到单个文件5.2MB
4. **manualChunks: undefined** - 无意义的显式配置
### 优化效果
| 指标 | 优化前 | 优化后 | 改善 |
|------|--------|--------|------|
| 主包大小 | 5,226 KB | 2,569 KB | ↓ 51% |
| 构建时间 | 33.64s | 17.14s | ↓ 49% |
| 代码分割 | 无(全部内联) | 按需加载 | ✅ |
详细文档: [CodeMirror-配置优化总结.md](./CodeMirror-配置优化总结.md)