- 前端
- UI组件
- 富文本
【免费下载链接】cherry-markdown
✨ A Markdown Editor
本文以 packages/client/CHANGELOG.md 的版本记录为主线,系统梳理@cherry-markdown/client(Cherry Markdown 的桌面客户端)从 0.1.1 到 0.5.1 的能力演进,并结合 packages/client/src 下的源码实现,深入解析导出、图床、本地版本记忆、所见即所得编辑等核心机制。读完本文,你将掌握该桌面客户端的完整功能地图、版本迁移注意事项,以及 Tauri 桌面环境下 Markdown 编辑器类功能的关键实现思路。
客户端定位与整体架构
Cherry Markdown 桌面客户端是基于 Cherry Markdown 核心渲染引擎开发的跨平台 Markdown 编辑器,底层使用 Tauri 2.x 构建桌面外壳,前端基于 Vue 3(vue@^3.5.13)、状态管理使用 Pinia(pinia@^3.0.4),并内嵌 CodeMirror 6(@codemirror/language、@codemirror/state、@codemirror/view)与 Milkdown(@milkdown/kit@^7.21.3)两套编辑器能力。从 packages/client/package.json 可以看到,它还集成了 KaTeX(公式渲染)、ECharts(图表)、pinyin(拼音转换)、viewerjs(大图预览)、html-docx-js-typescript(Word 导出)等第三方能力。
在布局上,客户端主界面由SidePanelManager(左侧工作区:目录树、最近文件、活动栏)、编辑器容器(#markdown-editor与#milkdown-editor双挂载点)、StatusBar(状态栏)以及若干对话框(设置、未保存确认、历史版本)组成,核心装配逻辑见 packages/client/src/App.tsx。
版本演进时间线:从基础导出到所见即所得
CHANGELOG 记录了该客户端从 0.1.1 到 0.5.1 的完整演进,以下是按功能主题梳理的版本脉络:
0.1.1:建立发布基建与基础导出能力
- 引入
changesets作为版本管理与发布流程自动化工具,为多包协同发布(客户端 + 主包 cherry-markdown)打下基础。 - 新增
export函数,支持导出pdf、html、md、png四种格式。这奠定了客户端「导出能力」的第一版,后续 0.5.1 在此基础上扩展为五种格式。 - 同步升级了
eslint@8.x与prettier@3.x等工程化依赖。
0.2.0:默认主题调整(Breaking Change)
此版本包含一次破坏性变更,主题体系被重构:
- 移除
light主题:原本的light主题被删除,新的default主题成为默认主题(对应themeSettings.mainTheme)。 - 影响范围:对于在配置项
themeSettings.mainTheme中使用light主题的用户,由于该主题已不存在,主题会自动切换为default(即原先的light)。 - 迁移指南:
- 若你之前使用
light主题:主题会自动切换到default,可选操作是将mainTheme: 'light'显式改为mainTheme: 'default'; - 若你自定义过
light主题:把原light.scss底部的配置项迁移到default.scss; - 若你自定义过
default主题:将原default.scss底部的配置项迁移到新的default.scss。
- 若你之前使用
该版本还包含若干编辑体验修复:新增自定义代码块语言配置all、表格添加列时对齐方式优先取左列(无则取右列)、修复选中标题时选区被意外扩大的问题。
0.2.1:流式渲染与代码块体验优化
- 代码块工具栏的定位逻辑从
px单位改为em,提升不同缩放下的稳定性。 - 目录(TOC)中特殊标记被引用的标题,方便快速定位引用关系。
- 增加代码块外层容器的自定义能力(对应
codeBlock.wrap等配置)。 - 针对流式渲染场景(
global.flowSessionContext=true)优化了 Mermaid 渲染失败的处理逻辑:单个 Mermaid 渲染失败时保持上次成功渲染的 SVG;多个 Mermaid 时向上寻找最近一次渲染成功的 SVG 进行替换。同时在「流式输出 + 未开启预览区编辑(enablePreviewerBubble=false)」时精简不必要的 DOM,但 CHANGELOG 也明确指出这种精简在需要switchModel时会存在问题。
0.3.0:图表、公式、拼音能力引入
- 客户端开始支持图表(ECharts)、公式(KaTeX)、拼音等 Markdown 扩展能力,这些能力都通过主包 Cherry 的语法系统与
externals配置注入,具体装配可见 packages/client/src/components/CherryMarkdown.ts。 - 工程层面将
@types/node升级至@20.10.6。
0.3.1:Windows 路径修复
修复 Windows 下的路径报错问题,属于桌面端跨平台适配的关键修复。
0.4.0:UI 重构与桌面端体验增强
这是客户端体验层面的重要节点:
- UI 组件从 Vue SFC 迁移为 TSX:保留原有文件、编辑器和状态栏行为,但组件形态全面 TSX 化(仓库中 packages/client/src/components 下的
DirectoryTree.tsx、SidePanelManager.tsx、StatusBar.tsx等均为此架构)。 - 左侧工作区增强:支持面板宽度拖拽、图标提示、当前文件定位、右键菜单视口避让(避免菜单被窗口边缘裁切)、最近文件按日期分组。
- 系统级文件关联:支持在 macOS Finder 中通过文件关联直接打开 Markdown/Text 文件,并保留 Windows 双击打开能力。文件关联配置见 packages/client/src-tauri/tauri.conf.json 的
bundle.fileAssociations,注册了md、markdown、txt、text四种扩展名。 - Windows 文本预览处理器:安装时注册系统自带文本预览处理器,使资源管理器预览窗格可直接查看
.md/.markdown源码;安装向导支持「为当前用户」或「为所有用户」安装,卸载时一并清理(对应 NSIS 的installMode: "both"与自定义installer-hooks.nsi)。 - 专注模式:底部状态栏新增「专注模式」开关;预览模式下支持点击图片查看大图;统一图标风格,优化悬浮目录样式;纯预览模式时将预览区最大宽度限制为 1024px。
- 修复编辑区无法滚动的问题。
0.4.1:记忆能力与图床设置
- 增加等宽字体选项。
- 增加记忆能力:客户端会记忆用户偏好与编辑器状态(如编辑器模式、主题选择等),通过
usePreferencesStore持久化。 - 增加设置图床功能:用户可在设置对话框中配置图床(none / PicGo / 自定义),图床的三种实现详见下文「图床上传机制」。
- 主题联动优化:Cherry 的主题可与编辑器主体联动切换。
0.5.0:所见即所得编辑模式
- 客户端新增所见即所得(WYSIWYG)编辑模式,基于 Milkdown 实现。从仓库结构看,
#markdown-editor(Cherry 双栏/源码编辑)与#milkdown-editor(WYSIWYG)双挂载点并存,通过 packages/client/src/components/composables/useEditorAdapter.ts 统一适配两种编辑器,上层文件操作、保存、版本管理等逻辑对编辑器类型无感。 - 同步优化工具栏样式并同步时间线工具栏。
0.5.1:五种导出与安全加固
- 导出能力扩展为长图、PDF、Docs(Word)等五种格式:至此客户端支持 markdown、html、pdf、screenShot(长图)、word 五种导出。
- 修复导出 Word 后出现弹窗无法关闭的问题(弹窗时序与焦点管理问题)。
- 安全加固:修复
brace-expansion受影响版本引起的高危拒绝服务漏洞(CVE-2026-13149),并将相关依赖链更新到已修复版本。
核心能力深度解析(结合源码)
五种导出格式的实现原理
客户端自实现runCherryExport(packages/client/src/components/composables/useCherryExport.ts),原因是 Tauri(WebView2 / WKWebView)环境下浏览器原生的<a download>不会触发系统下载器,主包utils/export.js中 Blob +a.click()的方案会静默失效,window.print也没有真正的打印对话框。五种导出各自的落地方式如下:
| 导出类型 | 实现方式 | 关键细节 |
|---|---|---|
| markdown | dialog.save+fs.writeTextFile | 直接写cherry.getMarkdown()文本 |
| html | dialog.save+fs.writeTextFile | 由buildFullHtmlDocument生成「自包含」HTML5 文档:内联全部可读样式表的cssRules,跨域样式表降级为<link>;剔除cherry-previewer--hidden、cherry-previewer--full运行时类名,避免导出文档白屏或样式漂移 |
克隆预览区 +window.print() | Tauri 系统 WebView 支持window.print()弹出原生打印对话框,用户可选择「Microsoft Print to PDF」或「另存为 PDF」;通过@page { margin: 0 }去除打印页眉页脚,用.cherry-export-wrapper内边距代替页边距 | |
| screenShot(长图) | html2canvas 分片截图 + 主画布拼接 | 跨域图片先抓取为 data URL(fetch CORS→no-cors→<img crossorigin>+canvas三级降级);按高度切片避免单边 16384px 上限,每片高 scale 渲染后拼接到主画布,任意长度文档保持清晰度 |
| word | html-docx-js-typescript.asBlob生成 .docx | 动态import减小首屏体积;跨域图片转 data URL 后打包;asBlob失败时降级为「复制富文本 HTML 到剪贴板」,用户可在 Word 中 Ctrl+V 粘贴(通过navigator.clipboard.write→document.execCommand('copy')事件劫持 →writeText三级降级) |
导出菜单通过Cherry.createMenuHook('导出', ...)注册为自定义菜单,子菜单项在afterInit中绑定bindSubClick(type),点击后调用runCherryExport。导出文件的默认名按「当前打开文件 basename → CherrygetFirstLineText→ Markdown 首行去掉#→ 兜底cherry-export」的优先级推断,并经过非法字符清洗与 80 字符截断。
图床上传机制:none / PicGo / 自定义
客户端在「设置」中提供图床配置(packages/client/src/components/composables/useImageBedUploader.ts),核心是uploadImageFile(file)按store.provider分发:
- none:走 Cherry 默认逻辑,即读取为 base64 data URL 内联。
- picgo:向 PicGo Server 端点 POST
{ list: [base64DataUrl] },期望返回{ success, result: [url] };失败自动降级为 base64。 - custom:以
multipart/form-dataPOST 到自定义 URL(可配置字段名、自定义请求头),JSON 响应时按responseUrlPath(点路径,支持data.url、result.0.url等)提取 URL,纯文本响应时直接取文本内容。
同时提供了粘贴场景的完整链路:createImageBedOnPaste在剪贴板含图片且已配置图床时,先同步返回<<正在上传图片…>>占位符,图片并行上传完成后通过 Cherry 的 asyncCallback 替换为真实语法;若剪贴板同时含有非空文本或未配置图床,则交给 Cherry 默认处理。还提供testImageBedConnection用于连通性测试(PicGo 用 1x1 透明 PNG 实测上传,自定义用 HEAD 探测可达性)。图床上传回调被装配在 packages/client/src/components/CherryMarkdown.ts 的callback.fileUpload与callback.onPaste中。
本地版本记忆与恢复
「记忆能力」不只是记住界面偏好,还包括文档的本地版本管理(packages/client/src/services/localVersions.ts + packages/client/src/components/composables/useLocalVersioning.ts)。其工作机制从 packages/client/src/App.tsx 可以看到:
- 内容变更时防抖写入 IndexedDB(
localVersioning.onContentChanged),状态栏展示最近自动保存时间与是否有历史版本; - 打开文件后通过
maybePromptRestore对比本地版本与磁盘内容:本地版本更新且内容有差异时,通过带「应用本地版本」按钮的 toast 提示用户恢复,不阻塞界面;切换文件时会先关闭上一份文件的残留提示,点击恢复时也会校验当前文件是否已切换,避免误伤; VersionHistoryDialog提供历史版本浏览与一键应用,应用后标记未保存状态并刷新窗口标题。
编辑器配置要点(以客户端实际配置为准)
packages/client/src/components/CherryMarkdown.ts 中的cherryConfig是客户端接入主包的标准范本,几个关键配置项:
- engine.global.classicBr: false:一个换行转
<br>,两个连续换行分割段落,三个以上连续换行转<br>并分割段落。 - syntax.codeBlock:开启行号(
lineNumber: true)、复制/编辑/切换语言按钮、代码块展开收起(超过 10 行自动收起)、Mermaidsvg2img: false、indentedCodeBlock: false(禁用缩进代码块语法)。 - editor.defaultModel: 'edit&preview':双栏编辑预览模式,支持
editOnly与previewOnly;实际运行时会被usePreferencesStore().editorMode持久化值覆盖;keyMap: 'sublime'快捷键风格,支持 vim。 - toolbars.toolbar:包含加粗、斜体组、字号、颜色、标题、列表、面板、对齐、时间线、折叠块、插入(图片/链接/分割线/代码/引用/目录/表格/drawio)、公式、图表、表格图表、搜索、快捷键等。
- toolbars.sidebar:
['customMenuChangeModule', 'customExport', 'mobilePreview', 'theme', 'codeTheme'],其中customMenuChangeModule负责在「双栏 / 纯编辑 / 纯预览」三种模式间切换并同步 pinia 状态,customExport即上文导出菜单。 - themeSettings:主题列表含 default(明亮)、dark(暗黑)、green(清新)、red(热情)、violet(淡雅)、blue(清幽),默认
mainTheme: 'violet'、codeBlockTheme: 'twilight'。注意 0.2.0 之后light主题名已不可用。 - previewer.lazyLoadImg:
noLoadImgNum: 5(前 5 张直接加载)、autoLoadImgNum: 5(再自动加载 5 张)、maxNumPerTime: 2(同一时间最多 2 个图片请求)、maxTryTimesPerSrc: 2。 - nameSpace: 'cherry':相同 namespace 的实例共享 localStorage 缓存。
构建、运行与桌面集成
客户端的前端部分使用 Vite + vue-tsc 构建,桌面壳通过 Tauri 2 封装。可执行脚本见 packages/client/package.json:
npm run dev:启动 Web 开发服务器(含scripts/sync-version.js版本同步);npm run tauri:dev:启动 Tauri 桌面开发模式;npm run build:类型检查 + Web 构建;npm run tauri:build:产出桌面安装包。
packages/client/src-tauri/tauri.conf.json 定义了桌面端关键配置:主窗口 1600×800、最小 800×500;CSP 白名单允许asset:与asset.localhost资源加载;文件关联覆盖md/markdown/txt/text,角色为 Editor;Windows 安装包使用 NSIS(installMode: "both")并挂载自定义installer-hooks.nsi。Tauri 侧还启用了plugin-dialog、plugin-fs、plugin-global-shortcut、plugin-opener等插件(见依赖列表),支撑保存对话框、文件读写、全局快捷键与系统打开等能力。
版本升级与安全提示
- 若从早期版本升级,注意 0.2.0 的主题破坏性变更:
light主题名已被移除,default即原light的主题;自定义主题时请将light.scss的配置迁移至default.scss,并将mainTheme显式改为default。 - 0.5.1 修复了
brace-expansion依赖链的高危拒绝服务漏洞(CVE-2026-13149),建议升级到该版本及以后,避免使用受影响版本带来的安全风险。 - 导出长图与 Word 等耗时操作均有 loading 提示与失败降级路径(截图失败保留原图、Word 失败转剪贴板富文本),遇到「导出后弹窗无法关闭」类问题时应优先检查异步弹窗/对话框的时序管理。
综上,@cherry-markdown/client的版本演进清晰地呈现了一条「基础导出 → 桌面体验打磨 → 所见即所得 → 安全加固」的产品路径,其源码中自实现导出、图床分发、本地版本恢复等设计,也是 Tauri 桌面端嵌入 Web 编辑器的可复用参考实现。
- 前端
- UI组件
- 富文本
【免费下载链接】cherry-markdown
✨ A Markdown Editor
相关推荐
ONNX GraphSurgeon 演进全解:从版本变更记录看 ONNX 模型编辑器的核心能力
ONNX GraphSurgeon 演进全解:从版本变更记录看 ONNX 模型编辑器的核心能力 ONNX GraphSurgeon(简称 gs)是 NVIDIA
人工智能推理引擎深度学习本地部署模型优化Cherry Markdown 桌面客户端深度指南:Tauri v2 双引擎 Markdown 编辑器的架构、模式与实战配置
Cherry Markdown 桌面客户端深度指南:Tauri v2 双引擎 Markdown 编辑器的架构、模式与实战配置 Cherry Markdown C
前端UI组件富文本Joplin 桌面端版本演进全解析:从 v0.10 到 v3.7 的核心功能与实现原理
Joplin 桌面端版本演进全解析:从 v0.10 到 v3.7 的核心功能与实现原理 本篇技术指南以 Joplin 桌面端官方 Changelog( read
知识管理跨平台插件系统
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考