知行札记
专题技术实践文档与编辑工具

Monaco 与 CodeMirror 代码编辑接入

分开文件模型、编辑视图和语言服务,处理生命周期、Worker、保存与多文件操作。

先分开文件、视图和服务

代码编辑组件显示可编辑文本,通常还维护 selection、撤销、诊断和语言能力。文件内容模型可以独立于当前面板,一个文件可能在多个视图中打开。关闭面板是否销毁文件模型,需要由应用的文档生命周期决定。

Monaco 把文本、语言和编辑历史放在 model 中,以 URI 标识模型;editor 是用户看到的视图,provider 提供补全等能力。URI 会参与 TypeScript 导入或 JSON schema 等语言服务判断,稳定 URI 比每次新建匿名模型更利于多文件项目。Monaco README

import * as monaco from 'monaco-editor';

const uri = monaco.Uri.parse('inmemory://project/notes/example.ts');
const model = monaco.editor.getModel(uri)
  ?? monaco.editor.createModel('export const value = 1;', 'typescript', uri);
const view = monaco.editor.create(container, { model, automaticLayout: true });

const subscription = model.onDidChangeContent(() => {
  queueSave(model.getValue(), model.getVersionId());
});

// 面板卸载:解除本面板的订阅并释放视图。
subscription.dispose();
view.dispose();
// model 由项目文档管理器在所有使用者关闭后释放。

container 和 queueSave 为应用提供的接线边界。模型的本地版本号用于区分编辑变化,不自动成为服务端修订号。把同一 model 重绑到另一个视图时应同时恢复该面板的 selection 和滚动状态。

Worker 和部署路径是语言服务的一部分

Monaco 的语言服务可使用 Worker。Vite 等构建器需要按所用语言配置正确 Worker 入口,相关资源受基础路径、CSP、源和部署方式影响。编辑器能显示文字不足以证明 TS、JSON 或其他语言服务已工作。

只初始化所需语言和功能可以降低下载与初始化成本。React 包装器也应核对加载来源;使用远程默认 CDN 与将资源随站点分发具有不同网络、版本和 CSP 条件。选择自托管时,把 Worker 和样式视为实际发布产物。

Monaco 可以使用语言服务 provider;VS Code 扩展整体不能直接复制到浏览器 Monaco。某项 LSP 方案还需要协议客户端、传输、语言服务器及工作区语义。浏览器中的代码文本也不自动具有执行环境,运行用户代码属于另一条隔离执行链路。

CodeMirror 6 的状态与视图

CodeMirror 6 用扩展组成状态、语言、快捷键和视图能力。文档变化通过 transaction 更新状态,视图负责显示及输入。大型 IDE 型任务可以采用 Monaco;轻量嵌入、多实例或高度定制输入可以评估 CodeMirror。这个分支来自任务特点,未用本轮包体或性能测量证明任何库整体胜出。

CodeMirror 的库按状态、视图、语言等模块组合。项目需保留兼容的一组包,避免混装不同实例导致扩展识别失败。React 包装器的值同步要避免每次渲染都重建 EditorState,否则 selection 与撤销历史会丢失。改变主题或只读能力宜使用相应重新配置机制,并核查包装器的接口。

语法高亮依赖语言解析或标记规则,诊断和补全依赖更具体的语言服务。启用“语言为 TypeScript”只说明选择了对应模式,不代表完整工程类型检查、路径别名或全部依赖已经接入。

保存与外部更新的冲突

编辑器本地修改、网络加载和外部推送是三种更新来源。首次加载可以初始化 model;后台重取若无条件覆盖当前内容,可能删除尚未保存的修改。保存响应应确认对应快照,新版本与本地未保存变化之间需要冲突策略。

多文件应用以文件身份维护内容、持久版本、待保存变化和打开视图。标签栏显示可派生状态,不能另存第二份文本与独立“已保存”布尔值。重命名会影响 URI、导入解析和后端身份,设计上明确文件 ID 是否稳定以及何时更新模型路径。

协同编辑时,本地文本变更应进入编辑器专用的协同绑定。直接用 setValue 反复覆盖远端文本会破坏 position 和撤销语义。模型建议或批量重写采用明确变换,并保存原内容版本供接受与冲突判断。

诊断、格式化与可访问交互

诊断包含范围、来源、严重程度和消息。异步检查返回时先核对文件身份及内容版本,过时诊断应丢弃或标记。格式化也应针对当前版本,并可作为一次撤销单元;不要让格式化反馈触发无限保存与再格式化循环。

编辑器拥有复杂快捷键,应保留焦点进入和退出的可预期方法、可访问名称及提示。输入法组合期间不要把中间文字当成最终程序执行。阅读模式、差异视图和执行按钮的权限分别控制。

本页整合归档代码编辑研究与落地材料。Worker 配置、移动端支持、LSP 包装器和框架版本需按所装依赖核查,本轮没有运行编辑器或浏览器语言服务。

最后更新于

本页目录