拆解Markra技术架构:Tauri 2 + React + CodeMirror 6构建WYSIWYG Markdown编辑器的完整指南
【免费下载链接】markra
A WYSIWYG Markdown editor with native AI. Fully open source. Free to use. Your data stays local.
Markra 是一款本地优先的 WYSIWYG Markdown 编辑器,使用 Tauri 2 + React + CodeMirror 6 构建,数据保存在本地,内置多供应商 AI 写作助手,完全开源免费。本文带你逐层拆解它的技术架构。
一、架构总览:一个 pnpm 单仓,五个可复用包
Markra 采用 pnpm workspace 组织代码,工作区定义见 pnpm-workspace.yaml:apps/放应用,packages/放可复用包。
| 目录 | 职责 |
|---|---|
| apps/desktop/ | 桌面应用(Tauri 2 壳 + React 前端 + Rust 后端) |
| apps/web/ | 可安装的 Web 版编辑器(PWA) |
| packages/app/ | 应用 UI 组件、hooks、设置逻辑 |
| packages/editor/ | CodeMirror 6 编辑内核与 WYSIWYG 预览扩展 |
| packages/editor-react/ | 编辑器与 React 的桥接层 |
| packages/ai/ | AI 供应商请求、Agent 运行时、AI 工具 |
| packages/shared/ | 跨端类型、i18n、纯工具函数 |
| packages/providers/ | AI 供应商目录、请求兼容层 |
这种分层带来一个关键能力:同一套 React UI 既能跑在桌面 WebView 里,也能跑在浏览器里。
二、第一层:Tauri 2 原生壳(Rust)
桌面端由 Tauri v2 驱动,配置见 tauri.conf.json:声明了.md/.markdown文件关联、macOS 原生菜单栏、Windows NSIS 安装钩子与自动更新插件。
Rust 后端入口 lib.rs 按功能拆成 30 个模块,每个模块对应一类原生能力:
- 文件与目录:
markdown_files负责读、写、重命名、历史;watcher提供文件系统监听,外部改动实时同步进编辑器; - 网络与 AI:
ai_http以 Rust 发起 AI 请求(绕过 WebView 的 CORS 限制),webdav_text_file、s3_text_file实现远端同步; - Agent 进程:
acp支持 Agent Client Protocol,可启动本地 AI Agent 并转发消息; - 窗口与系统:
windows、window_state管理多窗口恢复状态,spellcheck_dictionary管理按需下载的语言包。
前端通过这些 Rust command 获得"原生感":原生文件对话框、系统菜单、剪贴板、字体列表,全部在 desktopRuntime 中聚合成一个统一接口。
三、第二层:Runtime 抽象——一套 UI,两种运行环境
这是 Markra 架构中最值得借鉴的设计。packages/app定义了AppRuntime接口(见 runtime/index.ts),把文件、对话框、菜单、窗口、AI 请求等全部抽象为方法集合。
- 桌面端实现:apps/desktop/src/runtime/index.ts,全部走 Tauri
invoke调用 Rust; - Web 端实现:apps/web/src/runtime/web/,用浏览器 File System Access API、IndexedDB 等替代实现。
UI 层只依赖抽象接口,不感知自己在哪个平台运行。结果就是 Web 版编辑器与桌面版共享 95% 以上的业务代码。
四、第三层:CodeMirror 6 编辑内核
WYSIWYG 效果没有用"富文本 DOM"方案,而是建立在 CodeMirror 6 的StateField、decorations、widgets 之上——文档始终是纯 Markdown 文本,所见即所得只是渲染装饰。
编辑内核位于 packages/editor/src/codemirror/,60 多个模块各司其职:
- preview.ts:把 Markdown 语法树节点映射为 CSS 类与装饰,实现标题、表格、列表的"渲染外观";
- math-preview.ts、mermaid.ts:行内渲染 KaTeX 公式与 Mermaid 图表;
- slash-menu.ts、block-drag.ts:斜杠命令与块级拖拽;
- controller.ts:封装文档替换、搜索、AI 锚点定位等统一入口。
工程规范(见 AGENTS.md)要求:预览输出必须是确定性的——相同文档与配置重建编辑器,必须产生相同的装饰与几何布局;所有修改只走 CodeMirror transaction,禁止直接改 DOM。
React 通过 packages/editor-react/ 接入:MarkraEditorProvider用useSyncExternalStore订阅编辑器 revision,把编辑器状态安全地同步进 React 组件树。
五、第四层:内置 AI 与"预览后应用"流程
AI 能力由 packages/ai/ 提供,与编辑器解耦:
- 请求层:桌面端由 Rust
ai_http直连供应商(ai_http.rs),规避 CORS;Web 端走浏览器请求; - Agent 运行时:agent/runtime.ts 组装系统提示词、上下文窗口(如 1600 字符的局部上下文),流式返回事件;
- 工具与计划:
agent/tools/提供文档改写、网页搜索等工具,workspace-change-plan让 Agent 先产出变更计划; - 预览闸门:所有 AI 修改先渲染为 diff 预览(codemirror/ai-preview.ts),用户确认后才写入文档。
多供应商目录与请求兼容层在 packages/providers/,支持 OpenAI、Anthropic、Gemini、DeepSeek、Ollama 等十余种云端与本地模型。
六、工程化细节:小但关键
- 依赖补丁:用 pnpm
patchedDependencies修补 CodeMirror view 的 macOS 26 聚焦滚动问题,说明见 patches/README.md; - 共享构建配置:Vite 配置统一收敛在 packages/scripts/src/vite/,桌面与 Web 应用只传差异参数(见 apps/desktop/vite.config.ts);
- 测试:每个包自带 vitest,编辑器行为矩阵(行首/行尾、空白行、选区、模式切换)有专门测试约束;
- 本地优先:文件默认不落云端,WebDAV 同步与 S3 图片存储均为可选(docs/privacy.md)。
七、小结:这套架构能给你什么启发
| 层级 | 技术 | 核心价值 |
|---|---|---|
| 原生壳 | Tauri 2 + Rust | 轻量安装包、原生菜单/文件/剪贴板 |
| 运行环境 | Runtime 抽象接口 | 一份 UI 代码覆盖桌面与 Web |
| 编辑内核 | CodeMirror 6 | 纯文本 Markdown + 确定性 WYSIWYG 装饰 |
| AI 层 | packages/ai + providers | 多供应商、流式、预览后应用 |
| 工程 | pnpm workspace + patches | 包边界清晰、依赖可控 |
如果你想实现类似产品,建议从 AGENTS.md 中的"CodeMirror Editor Invariants"读起——它把 WYSIWYG 编辑器最容易踩坑的地方(DOM 漂移、几何不确定性、IME 组合输入)都写成了硬性规范,这正是 Markra 体验稳定的根本原因。
【免费下载链接】markra
A WYSIWYG Markdown editor with native AI. Fully open source. Free to use. Your data stays local.
相关推荐
SoloMD技术架构全解析:Tauri 2 + Vue 3 + CodeMirror 6如何构建仅32MB的本地优先编辑器
SoloMD技术架构全解析:Tauri 2 + Vue 3 + CodeMirror 6如何构建仅32MB的本地优先编辑器 SoloMD 是一款本地优先(loc
wechat-dump安全注意事项:合法使用数据导出工具
wechat dump安全注意事项:合法使用数据导出工具 wechat dump是一款用于从Android设备分析微信消息历史的工具,它能帮助用户导出和查看自己
即时通讯数据分析数据可视化逆向工程React CodeMirror:构建现代化代码编辑器的完整指南
React CodeMirror:构建现代化代码编辑器的完整指南 React CodeMirror 是一个优秀的 React 组件,它将功能强大的 CodeMi
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考