MarkLite

MarkLite

轻量级 Windows 本地 Markdown 编辑器

Platform Electron TypeScript React License Version

基于 Electron + React + TypeScript 构建的现代化 Markdown 桌面编辑器。
多标签页 · 实时预览 · 代码高亮 · 暗色主题 · 拖拽打开 · 搜索替换 · 文件树 · IndexedDB 持久化。

--- ## ✨ 功能特性 | 功能 | 说明 | |------|------| | 📑 **多标签页** | 同时打开多个文件,Ctrl+T 新建、Ctrl+W 关闭、Ctrl+Tab MRU 切换 | | 📂 **文件打开** | 按钮打开 / 拖拽打开 / 文件关联(双击 .md) / 命令行参数 | | ✏️ **实时编辑** | 左侧编辑器,支持 Tab 缩进、行号显示、光标位置、大文件虚拟化行号 | | 👁 **实时预览** | 右侧预览面板,基于 unified/rehype 管线渲染,编辑即更新 | | 🔤 **代码高亮** | 基于 rehype-highlight,支持 180+ 种编程语言语法高亮 | | 🎨 **三种视图** | 分屏模式 / 纯编辑 / 纯预览,自由切换 | | 📐 **分屏调节** | 拖拽中间分隔条,自由调整编辑区与预览区比例 | | 🌙 **暗色主题** | 一键切换亮色/暗色主题,偏好自动记忆(IndexedDB) | | 🔔 **文件监听** | 外部修改文件时自动提示,支持重新加载或忽略 | | 💾 **文件保存** | 保存 / 另存为,支持 .md / .markdown / .txt 格式 | | 🔍 **搜索替换** | Ctrl+F 搜索、Ctrl+H 替换,支持高亮匹配、大小写、正则表达式 | | 📁 **文件树** | 侧边栏浏览项目目录,点击打开文件,目录变化自动刷新 | | 💾 **状态持久化** | 标签页状态、用户设置通过 IndexedDB 持久化,关闭后可恢复 | | ⌨️ **快捷键** | 完整的键盘快捷键支持,操作高效 | | 📦 **NSIS 安装包** | 一键打包为 Windows exe 安装程序 / 便携版 | ## 📸 界面预览 ``` ┌──────────────────────────────────────────────────────────────────────────┐ │ MarkLite - README.md ─ □ ✕ │ ├──────────────────────────────────────────────────────────────────────────┤ │ 📁 打开 │ 💾 保存 │ ⬜ 分屏 │ ✏️ 编辑 │ 👁 预览 │ 🌙 │ ├──────────────────────────────────────────────────────────────────────────┤ │ [README.md] [DESIGN.md] [main.ts] [+] │ ├──────────┬─────────────────────────┬─────────────────────────────────────┤ │ 资源管理器│ │ │ │ ▼ MarkLite│ 🔍 查找... 3/12 │ MarkLite │ │ 📁 src │ [替换... ] [替换][全部]│ ───────────── │ │ 📄 README│ │ │ │ 📄 DESIGN│ 1 # MarkLite │ 一款轻量级的 Windows 本地 │ │ 📁 lib │ 2 │ Markdown 编辑器桌面应用... │ │ 📁 assets│ 3 一款轻量级的... │ │ │ │ 4 │ ■ 实时编辑 │ │ │ 5 ## 功能特性 │ ■ 实时预览 │ │ │ 6 │ ■ 代码高亮 │ │ │ 7 - 📝 实时编辑 │ │ ├──────────┴─────────────────────────┴─────────────────────────────────────┤ │ README.md │ UTF-8 │ Markdown │ 2.1 KB │ 行 9, 列 12 │ └──────────────────────────────────────────────────────────────────────────┘ ``` ## 🚀 快速开始 ### 环境要求 - **Node.js** >= 18.x - **npm** >= 9.x - **Windows** 10/11 x64 ### 安装与运行 ```bash # 克隆仓库 git clone https://gitee.com/thzxx/MarkLite.git cd MarkLite # 安装依赖 npm install # 启动开发模式(带 HMR 热更新) npm run dev ``` ### 打包为 exe 安装包 ```bash # 打包 Windows x64 NSIS 安装包 npm run build # 打包为便携版(免安装) npm run build:portable ``` 打包完成后,安装包位于 `dist/` 目录。详见 [DEVSETUP.md](DEVSETUP.md)。 ### 其他命令 ```bash # TypeScript 类型检查 npm run typecheck # ESLint 代码检查 npm run lint ``` ## ⌨️ 快捷键 | 快捷键 | 功能 | |:-------|:-----| | `Ctrl + T` | 新建标签页 | | `Ctrl + W` | 关闭当前标签页 | | `Ctrl + Tab` | 切换到下一个标签页(MRU 顺序) | | `Ctrl + Shift + Tab` | 切换到上一个标签页 | | `Ctrl + O` | 打开文件 | | `Ctrl + S` | 保存文件 | | `Ctrl + Shift + S` | 另存为 | | `Ctrl + 1` | 编辑 + 预览(分屏) | | `Ctrl + 2` | 纯编辑模式 | | `Ctrl + 3` | 纯预览模式 | | `Ctrl + F` | 搜索 | | `Ctrl + H` | 搜索并替换 | | `Enter` / `Shift+Enter` | 下一个 / 上一个匹配 | | `Alt + C` | 切换区分大小写 | | `Alt + R` | 切换正则表达式 | | `Ctrl + Shift + G` | 替换当前匹配 | | `Ctrl + Shift + H` | 全部替换 | | `Esc` | 关闭搜索栏 | ## 🛠️ 技术栈 | 组件 | 技术 | 说明 | |:-----|:-----|:-----| | 桌面框架 | [Electron](https://www.electronjs.org/) v28 | 跨平台桌面应用框架 | | 前端框架 | [React](https://react.dev/) v18 | 函数组件 + Hooks | | 类型系统 | [TypeScript](https://www.typescriptlang.org/) v5.6 | 全量类型安全 | | 状态管理 | [Zustand](https://zustand-demo.pmnd.rs/) v5 | 轻量级状态管理 | | 持久化 | [Dexie.js](https://dexie.org/) v4 (IndexedDB) | 标签页状态 & 用户设置持久化 | | Markdown 解析 | [unified](https://unifiedjs.com/) / [remark](https://remark.js.org/) / [rehype](https://rehype.js.org/) | 插件化 Markdown 渲染管线 | | 代码高亮 | [rehype-highlight](https://github.com/rehypejs/rehype-highlight) | 基于 highlight.js 的语法高亮 | | 构建工具 | [electron-vite](https://electron-vite.org/) v3 | Electron + Vite 集成,HMR 热更新 | | 打包工具 | [electron-builder](https://www.electron.build/) | 生成 exe 安装包 | | 样式 | CSS Variables + CSS Modules | 主题驱动,样式隔离 | ## 📁 项目结构 ``` MarkLite/ ├── package.json # 项目配置 & 依赖 & electron-builder 打包配置 ├── tsconfig.json # TypeScript 配置 ├── tsconfig.node.json # Node 端 TypeScript 配置 ├── electron.vite.config.ts # electron-vite 构建配置 ├── .eslintrc.cjs # ESLint + TypeScript 规则 │ ├── src/ │ ├── main/ # ===== 主进程 (Node.js) ===== │ │ ├── index.ts # 入口:窗口创建、app 生命周期、单实例锁 │ │ ├── ipc-handlers.ts # 所有 ipcMain.handle 注册 │ │ ├── file-system.ts # 文件读写、目录树构建、BOM 剥离 │ │ ├── file-watcher.ts # fs.watch 封装(单文件 + 目录监听) │ │ ├── window-manager.ts # 窗口创建、关闭拦截、单实例锁 │ │ └── ipc-channels.ts # IPC 通道名常量 │ │ │ ├── preload/ # ===== 预加载脚本 ===== │ │ └── index.ts # contextBridge 类型安全暴露 │ │ │ ├── renderer/ # ===== 渲染进程 (React) ===== │ │ ├── index.html # 入口 HTML(含 CSP 策略) │ │ ├── main.tsx # React 入口 (createRoot) │ │ ├── App.tsx # 根组件:布局编排、全局事件 │ │ │ │ │ ├── components/ # ----- UI 组件 ----- │ │ │ ├── Toolbar/ # 工具栏(打开、保存、视图切换、暗色主题) │ │ │ ├── TabBar/ # 标签页栏(多标签、关闭、MRU 切换) │ │ │ ├── Editor/ # 编辑器(行号、大文件虚拟化、Tab 缩进) │ │ │ ├── Preview/ # Markdown 预览面板(unified/rehype 渲染) │ │ │ ├── Sidebar/ # 侧边栏文件树(递归、展开折叠、独立文件区) │ │ │ ├── SearchBar/ # 搜索替换栏(高亮、正则、大小写) │ │ │ ├── StatusBar/ # 状态栏(文件名、编码、语言) │ │ │ ├── WelcomeScreen/ # 欢迎屏幕 │ │ │ ├── Toast/ # Toast 通知 │ │ │ ├── ModifiedBanner/ # 文件外部修改提示横幅 │ │ │ └── DropOverlay/ # 拖拽文件覆盖层 │ │ │ │ │ ├── stores/ # ----- Zustand 状态管理 ----- │ │ │ ├── tabStore.ts # 标签页状态(tabs、activeTabId、mruStack) │ │ │ ├── editorStore.ts # 编辑器状态(viewMode、darkMode、splitRatio) │ │ │ ├── sidebarStore.ts # 侧边栏状态(tree、expandedDirs、rootPath) │ │ │ └── searchStore.ts # 搜索替换状态(matches、currentIndex、options) │ │ │ │ │ ├── hooks/ # ----- 自定义 Hooks ----- │ │ │ ├── useTheme.ts # 暗色/亮色主题(IndexedDB 持久化) │ │ │ ├── useSettings.ts # 用户设置读写 │ │ │ ├── useKeyboard.ts # 全局快捷键 │ │ │ ├── useDragDrop.ts # 拖拽打开文件 │ │ │ ├── useFileWatch.ts # 外部文件修改监听 │ │ │ └── useUnsavedWarning.ts # 未保存提醒(Electron + 浏览器兼容) │ │ │ │ │ ├── lib/ # ----- 工具库 ----- │ │ │ ├── markdown.ts # Markdown 渲染管线(unified → remark → rehype) │ │ │ ├── scrollSync.ts # 滚动同步算法(块级元素 DOM 位置映射) │ │ │ ├── searchEngine.ts # 搜索匹配引擎(普通/正则/大小写/二分查找) │ │ │ ├── fileUtils.ts # 文件大小格式化、扩展名检查 │ │ │ └── constants.ts # 常量定义 │ │ │ │ │ ├── db/ # ----- IndexedDB 持久化层 ----- │ │ │ ├── schema.ts # Dexie 数据库定义 + 类型(tabSnapshots/settings/recentFiles) │ │ │ ├── tabRepository.ts # 标签页状态 CRUD │ │ │ ├── settingsRepository.ts # 用户设置 CRUD │ │ │ └── recentFilesRepository.ts # 最近打开文件 │ │ │ │ │ ├── types/ # ----- TypeScript 类型 ----- │ │ │ ├── tab.ts # Tab 接口 │ │ │ ├── file.ts # FileNode, DirTree 等 │ │ │ ├── settings.ts # Settings 接口 + 默认值 │ │ │ ├── search.ts # SearchMatch, SearchOptions │ │ │ ├── ipc.ts # ElectronAPI 接口 + IPC 通道类型映射 │ │ │ └── index.ts # 类型统一导出 │ │ │ │ │ └── styles/ # ----- 全局样式 ----- │ │ ├── variables.css # CSS 变量(亮色/暗色主题) │ │ ├── global.css # 全局 reset + 布局 + 组件样式 │ │ └── markdown-body.css # Markdown 预览正文样式 │ │ │ └── shared/ # ===== 主进程/渲染进程共享 ===== │ ├── ipc-channels.ts # IPC 通道名常量 │ └── types.ts # 共享类型定义 │ ├── lib/ # 第三方离线库(marked.js, highlight.js) ├── assets/ │ └── icon.ico # 应用图标(多尺寸) ├── DESIGN.md # 架构设计文档 ├── DEVSETUP.md # 开发环境配置指南 ├── REFACTOR-PLAN.md # 重构方案文档 ├── LICENSE # MIT 许可证 └── README.md # 本文件 ``` ## 🏗️ 架构设计 ``` ┌─────────────────────────────────────────────────────────────┐ │ Main Process (src/main/) │ │ 窗口管理 · 文件系统 · 文件监听 · IPC · 目录树 · 单实例锁 │ └──────────────────────┬──────────────────────────────────────┘ │ contextBridge (安全隔离) ┌──────────────────────▼──────────────────────────────────────┐ │ Preload Script (src/preload/) │ │ 类型安全 API 桥接层 │ └──────────────────────┬──────────────────────────────────────┘ │ ┌──────────────────────▼──────────────────────────────────────┐ │ Renderer Process (src/renderer/) — React 18 │ │ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ Components (11 个) │ │ │ │ Toolbar · TabBar · Editor · Preview · Sidebar │ │ │ │ SearchBar · StatusBar · WelcomeScreen · Toast │ │ │ │ ModifiedBanner · DropOverlay │ │ │ └─────────────────────────────────────────────────────┘ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ Zustand Stores (4 个) │ │ │ │ tabStore · editorStore · sidebarStore · searchStore │ │ │ └─────────────────────────────────────────────────────┘ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ IndexedDB (Dexie.js) │ │ │ │ tabSnapshots · settings · recentFiles │ │ │ └─────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────┘ 安全策略:contextIsolation: true + nodeIntegration: false + CSP 渲染进程无法直接访问 Node.js API ``` ## 📝 支持的 Markdown 语法 - ✅ 标题(h1 ~ h6) - ✅ **粗体** / *斜体* / ~~删除线~~ - ✅ 有序列表 / 无序列表 - ✅ 任务列表 `- [x]` - ✅ 代码块(围栏式 + 语法高亮,180+ 语言) - ✅ 行内代码 - ✅ 链接 / 图片(支持相对路径) - ✅ 表格 - ✅ 引用块 - ✅ 水平线 - ✅ HTML 内联元素 - ✅ GFM(GitHub Flavored Markdown) ## 📄 许可证 [MIT License](LICENSE) © 2026 [thzxx](https://gitee.com/thzxx) ---

如果觉得有用,请点个 ⭐ Star 支持一下!