milkup-dev
milkup 开发环境工具
快速参考
milkup-dev 是专门为 milkup 项目设计的开发环境管理工具,深入了解项目的技术栈和架构。
milkup 是一个现代化的桌面端 Markdown 编辑器,基于 Electron 37+ 构建,使用 Vue 3 作为前端框架, Milkdown 作为编辑器核心,支持所见即所得(WYSIWYG)和源码编辑双模式。
自动触发:当用户请求启动开发环境、运行应用、进行开发调试或询问技术栈相关问题时。
技术栈概览
核心框架:
- Electron 37+ - 桌面应用框架(Chromium 130 + Node.js 20.18)
- Vue 3.5+ - 渐进式前端框架,使用 Composition API
- TypeScript 5.9+ - 类型安全的 JavaScript 超集,启用 strict 模式
- Vite 7+ - 下一代前端构建工具,提供极速的 HMR
编辑器核心:
- Milkdown 7.17+ - 基于 ProseMirror 的插件化 Markdown 编辑器
- @milkdown/crepe - Milkdown 的所见即所得(WYSIWYG)模式
- @milkdown/kit - Milkdown 完整插件套件
- CodeMirror 6 - 源码编辑模式的代码编辑器
- Vditor 3.11+ - 额外的 Markdown 编辑功能支持
构建工具链:
- Vite - 渲染进程构建和开发服务器
- esbuild - 主进程和预加载脚本的快速构建
- vite-plugin-electron - Electron 与 Vite 的集成插件
- electron-builder - 多平台应用打包工具
国际化与工具:
- vite-auto-i18n-plugin - 自动国际化翻译插件
- oxlint - 快速的 JavaScript/TypeScript 代码检查工具
- oxfmt - 快速的代码格式化工具
- simple-git-hooks - 轻量级 Git 钩子管理
UI 与增强:
- @vueuse/core - Vue 组合式 API 工具集
- vue-draggable-plus - 拖拽功能支持
- autodialog.js - 对话框管理
- autotoast.js - 通知提示管理
- mermaid - 图表渲染支持
项目架构
进程架构:
milkup 遵循 Electron 的多进程架构。主进程(Main Process)运行在 Node.js 环境中, 负责窗口管理、文件系统访问、IPC 通信处理和系统集成。渲染进程(Renderer Process) 运行在 Chromium 中,负责 UI 渲染和用户交互,通过预加载脚本(Preload Script) 与主进程进行安全的 IPC 通信。
目录结构:
src/
├── main/ # 主进程代码
│ ├── index.ts # 主进程入口,窗口创建和生命周期管理
│ ├── ipcBridge/ # IPC 通信处理器
│ ├── menu/ # 应用菜单定义
│ └── update/ # 自动更新逻辑
├── renderer/ # 渲染进程代码(Vue 应用)
│ ├── App.vue # 根组件
│ ├── main.ts # 渲染进程入口
│ ├── components/ # Vue 组件
│ │ ├── editor/ # 编辑器组件(Milkdown、CodeMirror)
│ │ ├── workspace/ # 工作区和标签页管理
│ │ ├── outline/ # 文档大纲导航
│ │ ├── menu/ # 菜单栏和状态栏
│ │ ├── settings/ # 设置页面
│ │ ├── dialogs/ # 对话框组件
│ │ └── ui/ # 通用 UI 组件
│ ├── hooks/ # Vue 组合式函数
│ ├── services/ # 业务逻辑服务
│ ├── plugins/ # Milkdown 插件
│ ├── styles/ # 样式文件
│ └── utils/ # 工具函数
├── preload.ts # 预加载脚本,暴露安全的 API 给渲染进程
├── shared/ # 主进程和渲染进程共享的类型和常量
├── types/ # TypeScript 类型定义
├── themes/ # 主题系统
├── plugins/ # 应用级插件
└── config/ # 配置文件
双窗口系统:
milkup 实现了双窗口架构。主窗口(Main Window)是主要的编辑器界面, 包含编辑器、工作区、大纲和菜单栏。主题编辑器窗口(Theme Editor Window) 是一个独立的模态窗口,用于自定义和编辑主题样式。两个窗口通过 IPC 通信 共享状态和数据。
路径别名配置:
项目配置了三个路径别名以简化导入:
@/- 指向src/目录,用于访问所有源代码@renderer/- 指向src/renderer/目录,用于渲染进程代码@ui/- 指向src/renderer/components/ui/目录,用于 UI 组件
核心功能特性
编辑器模式:
milkup 支持两种编辑模式的无缝切换。所见即所得模式(WYSIWYG)使用 Milkdown 的 Crepe 主题,提供类似 Typora 的即时渲染体验。源码模式使用 CodeMirror 6, 提供语法高亮、代码折叠和 Markdown 语法支持。两种模式共享同一份文档数据, 切换时保持光标位置和滚动状态。
文件管理:
应用支持多文件标签页管理,可以同时打开多个 Markdown 文件。工作区面板 显示文件树,支持文件夹展开/折叠和文件拖拽。文件关联功能允许双击 .md 文件 直接在 milkup 中打开。支持通过命令行参数启动时打开指定文件。
自定义协议:
实现了 milkup:// 自定义协议用于加载本地图片。协议格式为
milkup:///<base64-encoded-markdown-path>/<relative-image-path>,
解决了 Electron 中加载相对路径图片的安全限制问题。主进程注册协议处理器,
将相对路径解析为绝对路径并返回文件内容。
主题系统:
支持多主题切换和自定义主题编辑。主题文件使用 Less 编写,支持变量和嵌套。 主题编辑器提供可视化界面,可以实时预览主题效果。支持主题导入导出, 方便分享和备份。
国际化支持:
使用 vite-auto-i18n-plugin 实现自动国际化。支持中文、英文、日文、韩文、 俄文和法文。翻译文件自动生成,开发时只需编写中文文本,构建时自动翻译 为其他语言。
常用命令
启动开发服务器:
pnpm run dev
此命令会依次执行:
- 构建预加载脚本(esbuild)
- 构建主进程代码(esbuild)
- 启动 Vite 开发服务器
- 自动启动 Electron 应用(通过 vite-plugin-electron)
启动 Electron 应用:
pnpm run start:electron
此命令用于单独启动 Electron 应用,不启动 Vite 开发服务器。
构建主进程:
pnpm run build:main
构建预加载脚本:
pnpm run build:preload
实现指南
开发环境设置
环境要求:
开发 milkup 需要以下环境:
- Node.js >= 20.17.0(项目使用 Node.js 20.18 的特性)
- pnpm >= 10.0.0(项目使用 pnpm 10.12.1)
- Git(用于版本控制)
- 支持的操作系统:Windows、macOS 或 Linux
依赖安装:
首次克隆项目后,执行 pnpm install 安装所有依赖。项目配置了 preinstall
钩子,会检查是否使用 pnpm,如果使用其他包管理器会报错。安装过程中会自动
执行 simple-git-hooks 的 prepare 脚本,安装 Git 钩子。
开发服务器启动流程:
执行 pnpm run dev 后的完整流程:
- esbuild 构建预加载脚本(src/preload.ts → dist-electron/preload.js)
- esbuild 构建主进程代码(src/main/index.ts → dist-electron/main/index.js)
- Vite 启动开发服务器,监听 src/renderer 目录
- vite-plugin-electron 自动启动 Electron 主进程
- 主进程创建 BrowserWindow,加载 Vite 开发服务器的 URL
- 渲染进程加载 Vue 应用,初始化 Milkdown 编辑器
- 开发模式下自动打开 DevTools
环境变量:
开发模式下,vite-plugin-electron 会设置 VITE_DEV_SERVER_URL 环境变量,
主进程通过此变量判断是否为开发模式。开发模式下加载 Vite 开发服务器的 URL,
生产模式下加载本地 HTML 文件。
编辑器集成详解
Milkdown 集成:
Milkdown 是基于 ProseMirror 的插件化 Markdown 编辑器。项目使用 @milkdown/vue 提供的 Vue 组件集成。编辑器配置包括:
- @milkdown/preset-commonmark - CommonMark 规范支持
- @milkdown/preset-gfm - GitHub Flavored Markdown 支持
- @milkdown/plugin-prism - 代码块语法高亮
- @milkdown/plugin-diagram - Mermaid 图表支持
- @milkdown/plugin-listener - 编辑器事件监听
- @milkdown/plugin-automd - 自动 Markdown 格式化
Milkdown 编辑器组件位于 src/renderer/components/editor/MilkdownEditor.vue。 编辑器实例通过 Vue 的 provide/inject 机制在组件树中共享,允许其他组件 访问编辑器 API 进行内容操作。
CodeMirror 集成:
CodeMirror 6 用于源码编辑模式。配置包括:
- @codemirror/lang-markdown - Markdown 语法支持
- @codemirror/autocomplete - 自动补全
- @codemirror/commands - 编辑器命令
- codemirror-lang-mermaid - Mermaid 语法支持
CodeMirror 编辑器组件位于 src/renderer/components/editor/MarkdownSourceEditor.vue。 编辑器状态通过 @codemirror/state 管理,视图通过 @codemirror/view 渲染。
编辑器模式切换:
两种编辑器模式共享同一份 Markdown 文本数据。切换时,当前编辑器的内容 会保存到共享状态中,然后新编辑器从共享状态加载内容。使用防抖机制避免 频繁切换导致的性能问题。
IPC 通信模式
安全通信架构:
milkup 遵循 Electron 安全最佳实践。渲染进程启用 contextIsolation, 禁用 nodeIntegration。预加载脚本使用 contextBridge.exposeInMainWorld 暴露安全的 API 给渲染进程。渲染进程通过 window.electronAPI 访问主进程功能。
IPC 通信类型:
项目使用三种 IPC 通信模式:
-
invoke/handle 模式 - 用于请求-响应通信。渲染进程调用 ipcRenderer.invoke, 主进程通过 ipcMain.handle 注册处理器并返回结果。适用于文件读写、 对话框显示等需要返回值的操作。
-
send/on 模式 - 用于单向通信。渲染进程调用 ipcRenderer.send 发送消息, 主进程通过 ipcMain.on 监听。适用于通知类操作,不需要返回值。
-
webContents.send 模式 - 主进程主动向渲染进程发送消息。用于文件打开、 窗口关闭确认等主进程发起的操作。
IPC 处理器组织:
主进程的 IPC 处理器分为三类,位于 src/main/ipcBridge/ 目录:
- 全局处理器 - 不依赖窗口实例的处理器
- Handle 处理器 - 需要返回值的请求-响应处理器
- On 处理器 - 单向消息处理器
热重载机制
渲染进程热重载:
Vite 提供的 HMR(Hot Module Replacement)支持渲染进程的热重载。 修改 Vue 组件、样式文件或 TypeScript 代码时,Vite 会通过 WebSocket 推送更新,浏览器端的 HMR 客户端接收更新并替换模块,无需刷新整个页面。
Vue 组件的热重载由 @vitejs/plugin-vue 处理,支持保持组件状态。 修改组件模板或脚本时,只重新渲染受影响的组件,保持应用状态不变。
主进程热重载:
vite-plugin-electron 监听主进程和预加载脚本的文件变化。检测到变化时, 自动重新构建并重启 Electron 进程。这个过程会关闭当前窗口并创建新窗口, 因此会丢失应用状态。
为了减少主进程重启的影响,建议将业务逻辑尽量放在渲染进程,主进程只 处理必要的系统集成和 IPC 通信。
调试技巧
渲染进程调试:
开发模式下,应用启动时会自动打开 Chrome DevTools。也可以通过快捷键 Ctrl+Shift+I(macOS: Cmd+Option+I)或全局快捷键 Ctrl+Shift+I 打开。
DevTools 提供完整的调试功能:
- Console 面板 - 查看日志输出和执行 JavaScript 代码
- Sources 面板 - 设置断点、单步调试、查看调用栈
- Elements 面板 - 检查 DOM 结构和样式
- Network 面板 - 监控网络请求(虽然桌面应用较少使用)
- Performance 面板 - 性能分析和火焰图
- Memory 面板 - 内存分析和泄漏检测
Vue DevTools 集成:
可以安装 Vue DevTools 浏览器扩展的独立版本用于调试 Vue 应用。 在 DevTools 中可以查看组件树、组件状态、Vuex/Pinia 状态、事件追踪等。
主进程调试:
主进程运行在 Node.js 环境中,可以使用 Node.js 调试器。有两种方式:
-
VS Code 调试配置 - 在 .vscode/launch.json 中配置调试配置, 设置 Electron 可执行文件路径和启动参数,可以在 VS Code 中 直接设置断点调试主进程代码。
-
远程调试 - 使用 --inspect 或 --inspect-brk 标志启动 Electron, 然后在 Chrome 中访问 chrome://inspect 连接调试器。
日志输出策略:
主进程的 console.log 输出到终端,渲染进程的 console.log 输出到 DevTools。
建议使用不同的日志前缀区分不同模块,例如 [main]、[renderer]、[ipc] 等。
对于复杂的调试场景,可以使用 electron-log 库统一管理日志,支持日志级别、 文件输出和格式化。
Vue 组件调试:
在 Vue 组件中可以使用以下技巧:
- 使用
console.log在生命周期钩子中输出状态 - 使用 Vue DevTools 查看组件的 props、data 和 computed
- 使用
debugger语句设置断点 - 使用
watchEffect追踪响应式数据变化
Milkdown 调试:
Milkdown 编辑器的调试较为复杂,因为涉及 ProseMirror 的内部状态。 可以通过以下方式调试:
- 使用 @milkdown/plugin-listener 监听编辑器事件
- 访问编辑器实例的
ctx对象查看插件状态 - 使用 ProseMirror DevTools 查看文档结构和事务
故障排查
常见开发问题:
端口占用:
Vite 默认使用 5173 端口。如果端口被占用,Vite 会自动尝试下一个端口。
检查终端输出确认实际使用的端口号。如果需要固定端口,在 vite.config.mts
中配置 server.port。
白屏问题: 如果应用启动后显示白屏,按以下步骤排查:
- 打开 DevTools 查看 Console 是否有错误信息
- 检查 Network 面板确认资源是否正确加载
- 确认预加载脚本路径正确(dist-electron/preload.js)
- 检查主进程终端输出是否有错误
- 确认 Vite 开发服务器正常运行
热重载失效: 如果修改代码后页面没有更新:
- 确认 Vite 开发服务器正常运行,检查终端是否有错误
- 检查修改的文件是否在 Vite 监听的目录范围内(src/renderer)
- 尝试手动刷新页面(Ctrl+R 或 Cmd+R)
- 检查是否有语法错误导致 HMR 失败
- 重启开发服务器
IPC 通信失败: 如果渲染进程无法调用主进程功能:
- 确认预加载脚本正确暴露了 API(使用 contextBridge)
- 检查 IPC 通道名称是否匹配
- 确认主进程已注册对应的处理器
- 检查 contextIsolation 是否正确启用
- 在 DevTools Console 中检查 window.electronAPI 是否存在
编辑器加载失败: 如果 Milkdown 或 CodeMirror 编辑器无法正常显示:
- 检查编辑器组件是否正确挂载
- 确认编辑器样式文件已正确导入
- 检查 Console 是否有插件加载错误
- 确认编辑器容器元素存在且有正确的尺寸
- 检查是否有 CSS 冲突影响编辑器样式
构建失败: 如果 esbuild 或 Vite 构建失败:
- 检查 TypeScript 类型错误
- 确认所有导入路径正确
- 检查是否有循环依赖
- 确认 node_modules 完整安装
- 尝试删除 node_modules 和 pnpm-lock.yaml 重新安装
主题不生效: 如果自定义主题没有应用:
- 检查主题文件路径是否正确
- 确认 Less 文件语法正确
- 检查主题变量是否正确覆盖
- 确认主题文件已在入口文件中导入
- 清除缓存并重新构建
开发工作流
典型开发流程:
-
启动开发环境
- 执行
pnpm run dev启动开发服务器 - 等待 Electron 应用自动启动
- 确认 DevTools 已打开
- 执行
-
功能开发
- 在 src/renderer 中修改 Vue 组件或添加新组件
- 保存文件后查看 HMR 自动更新效果
- 使用 DevTools 调试和验证功能
-
主进程开发
- 修改 src/main 中的主进程代码
- 保存后等待 Electron 自动重启
- 在终端查看主进程日志输出
-
IPC 通信开发
- 在 src/main/ipcBridge 中添加 IPC 处理器
- 在 src/preload.ts 中暴露 API
- 在渲染进程中通过 window.electronAPI 调用
- 使用 TypeScript 类型确保类型安全
-
样式调整
- 修改 Less 文件或组件样式
- 使用 DevTools Elements 面板实时调试样式
- 保存后查看 HMR 更新效果
-
代码检查
- 定期执行
pnpm run lint检查代码质量 - 执行
pnpm run format自动格式化代码 - Git 提交前会自动运行 lint-staged
- 定期执行
-
测试验证
- 在开发环境中测试功能
- 执行
pnpm run build构建生产版本 - 执行
pnpm run start:electron测试构建产物
最佳实践:
- 使用 TypeScript 类型系统避免类型错误
- 遵循 Vue 3 Composition API 最佳实践
- 保持组件单一职责,避免过大的组件
- 使用 Vue 组合式函数(hooks)复用逻辑
- IPC 通信使用类型安全的接口定义
- 主进程代码保持简洁,业务逻辑放在渲染进程
- 使用路径别名简化导入语句
- 定期运行代码检查和格式化
- 提交前确保代码通过 lint 检查
使用示例
启动开发环境
基本启动:
# 安装依赖(首次或依赖更新后)
pnpm install
# 启动开发服务器和 Electron 应用
pnpm run dev
应用会自动启动,DevTools 会自动打开。终端会显示 Vite 开发服务器的地址 和构建信息。
单独构建主进程:
# 只构建主进程代码
pnpm run build:main
# 只构建预加载脚本
pnpm run build:preload
开发新功能
添加新的 Vue 组件:
# 在 src/renderer/components 中创建新组件
# 使用路径别名导入
import MyComponent from '@renderer/components/MyComponent.vue'
添加新的 IPC 通信:
// 1. 在 src/main/ipcBridge 中添加处理器
ipcMain.handle('my-channel', async (event, arg) => {
// 处理逻辑
return result
})
// 2. 在 src/preload.ts 中暴露 API
contextBridge.exposeInMainWorld('electronAPI', {
myFunction: (arg) => ipcRenderer.invoke('my-channel', arg)
})
// 3. 在渲染进程中调用
const result = await window.electronAPI.myFunction(arg)
调试场景
调试渲染进程:
# 启动开发环境
pnpm run dev
# DevTools 会自动打开
# 在 Sources 面板设置断点
# 在 Console 面板执行代码
调试主进程:
# 方式 1: 使用 VS Code 调试配置
# 在 .vscode/launch.json 中配置后,按 F5 启动调试
# 方式 2: 使用 --inspect 标志
# 修改 package.json 的 dev 脚本添加 --inspect
# 然后在 Chrome 中访问 chrome://inspect
测试构建
构建并测试:
# 完整构建
pnpm run build
# 启动构建后的应用
pnpm run start:electron
这会加载 dist 目录中的构建产物,而不是 Vite 开发服务器。 用于验证生产构建是否正常工作。
配合使用
- milkup-build - 构建生产版本和打包应用
- milkup-lint - 代码质量检查和格式化
- milkup-release - 版本发布和更新日志生成
- moai-framework-electron - Electron 开发最佳实践和高级模式
技术资源
配置文件:
- vite.config.mts - Vite 和 Electron 插件配置
- tsconfig.json - TypeScript 编译配置
- package.json - 依赖和脚本配置
关键文件:
- src/main/index.ts - 主进程入口,窗口管理和生命周期
- src/preload.ts - 预加载脚本,IPC API 暴露
- src/renderer/main.ts - 渲染进程入口,Vue 应用初始化
- src/renderer/App.vue - 根组件,应用布局
编辑器组件:
- src/renderer/components/editor/MilkdownEditor.vue - Milkdown 编辑器
- src/renderer/components/editor/MarkdownSourceEditor.vue - CodeMirror 编辑器
官方文档:
- Electron 文档: https://www.electronjs.org/docs
- Vue 3 文档: https://vuejs.org/
- Vite 文档: https://vitejs.dev/
- Milkdown 文档: https://milkdown.dev/
- CodeMirror 文档: https://codemirror.net/
Version: 2.0.0 Last Updated: 2026-01-30 Changes: 添加完整的技术栈说明、架构详解、开发工作流和调试指南