项目架构
概述
.:配置文件package.json:项目设置out/:编译后的源代码(main、preload、renderer 包)dist/:用于分发的打包二进制文件和安装程序resources/:应用程序资源(主题、图标等),包含在构建产物中docs/:文档和资源node_modules/:依赖项src:MarkText 源代码common/:只需 Node.js API 的通用源文件。此文件夹中的代码可用于除muya之外的所有其他文件夹。main/:需要 Electron 主进程 API 的主进程源文件。main文件可以使用common中的源代码。muya/:MarkText 的后端,仅使用纯 JavaScript、BOM 和 DOM API。不要使用 Electron 或 Node.js API。renderer:需要 Electron 渲染进程 API 的前端,可以使用common或muya中的源代码。
static/:应用程序资源(图片、主题等)test/:包含(单元)测试
MarkText 简介
MarkText 是一个支持多种 Markdown 扩展的实时预览(所见即所得)Markdown 编辑器,我们的理念是保持简洁、简单和最小化。该应用使用 TypeScript、Vue 3 和 CSS 构建,基于 Electron 运行(Muya 编辑器后端目前仍使用 JavaScript)。我们使用了一些原生 Node 库和 Pinia 来管理渲染进程的状态。MarkText 可以分为三个部分:核心 Muya、主进程和渲染进程。
Muya 通过基于块结构的多个模块提供实时预览和 Markdown 编辑功能。你可以将其想象为编辑器后端,包含 Markdown 解析模块、以块结构存储数据、按照 CommonMark 和 GitHub Flavored Markdown 规范(以及一些额外规范)进行 Markdown 文档转换、事件监听器,以及一个导出器,用于生成独立的 HTML 和 Markdown 文件,同时也生成所见即所得编辑器。Muya 是单线程的,MarkText 也是如此,但使用异步函数来提升性能。
注意:MarkText 的源代码编辑器由 CodeMirror 提供,优化程度不高,功能也不丰富。它不是 Muya 的一部分,而是编辑器(渲染进程)的一个功能,它从 Muya 加载 Markdown 文本(导出),对其进行操作,并在切换回预览模式时将文本重新导入 Muya。
注意:Muya 需要进行核心重构,以提供更好的模块化、API 和插件支持。此外,数据结构也需要改进以获得更好的性能和稳定性。
编辑器代表视图层,分为两个部分。第一部分是主进程,可以完全访问 Electron 和所有操作系统功能。它主要用于 IO、与原生对话框的用户交互以及控制编辑器窗口。主进程不应被同步操作(长时间)阻塞。渲染进程是真正的编辑器,也是 Muya 的宿主。它负责所有图形元素(src/renderer/components)、数据(src/renderer/store)和数据同步。每个窗口会生成一个渲染进程,独立运行并受主进程控制。它包含两个文本编辑器:由 Muya 提供的实时预览编辑器和由 CodeMirror 提供的源代码编辑器,具有选项卡、侧边栏和编辑功能等特殊功能。
应用入口点
应用有两个入口点:
src/main/index.ts用于主进程,它首先执行且每个实例仅执行一次。应用初始化后,可以安全地访问所有环境变量和单例,应用程序(App)也随之启动(src/main/app/index.ts)。在App::init()成功运行后即可使用该应用。src/renderer/src/main.ts用于每个编辑器窗口。初始时加载库,初始化窗口并挂载 Vue 组件。
Muya 如何工作
待补充
- Muya 组件概览
- Muya 内部工作原理
- 数据结构
主进程与渲染进程通信
主进程和渲染进程通过进程间通信(IPC)进行异步通信,主要用于 IO 和与原生对话框的用户交互。
编辑器窗口(渲染进程)
待补充
示例
打开一个 Markdown 文档并渲染它
MarkdownDocument 是一个表示磁盘上的 Markdown 文件或未命名文档的文档对象。要获取 Markdown 文档,可以使用 loadMarkdownFile 函数,它在主进程中异步返回一个 RawMarkdownDocument(= MarkdownDocument 加上一些附加信息)。
打开文件的整体步骤:
- 点击
File -> Open File,显示文件对话框,发出app-open-file-by-id事件,携带要打开文件的编辑器窗口 ID 和解析后的绝对文件路径。 - 应用(
App实例)尝试找到指定的编辑器并在该编辑器窗口上调用openTab。如果没有编辑器窗口存在,则创建一个新的编辑器窗口。 - 编辑器窗口通过
loadMarkdownFile尝试加载 Markdown 文件,并通过mt::open-new-tab事件将结果发送到渲染进程。- 每个打开的文件也会添加到文件系统监视器中,并保存完整路径以跟踪当前编辑器窗口中已打开的文件。
- 事件在
src/renderer/src/store/editor.ts(渲染进程)中触发,进行一些检查并创建一个新的文档状态,表示一个 Markdown 文档和选项卡状态。 - 新创建的选项卡要么被打开并发出
file-changed事件,要么只是添加到选项卡状态中。 - Muya 和源代码编辑器都会监听此事件,并相应地更改 Markdown 文档。
注意:目前我们还没有高级 API 来自动更改文档文本或行。所有修改都需要用户交互!