用 Rust 写一个 1MB 的 Markdown 预览工具,替代 200MB 的 Electron 方案

2 阅读2分钟

背景

作为开发者,我们每天都在写 Markdown。但预览工具要么太重(VS Code 300MB+),要么要收费(Typora),要么功能臃肿。

我只想要一个纯粹的预览工具:拖个文件进去,漂亮地渲染出来,改了自动刷新。不需要编辑,不需要插件系统,不需要云同步。

于是我用 Rust 写了一个,最终二进制只有 1.1MB

技术选型

组件选择为什么
语言Rust零成本抽象,编译后体积小
GUIwry调用系统 WebView,不打包 Chromium
Markdown 解析pulldown-cmark纯 Rust,支持 GFM
代码高亮highlight.js40+ 语言,内嵌到二进制
文件监听notify跨平台文件 watcher
文件对话框rfd原生系统对话框

关键决策:用系统 WebView 而不是 Electron

macOS 自带 WebKit,Windows 有 WebView2,Linux 有 WebKitGTK。wry 这个库帮你统一了接口,你只需要给它 HTML,它帮你渲染。

结果就是:不需要打包一个 150MB 的 Chromium,二进制直接从 150MB 降到 1MB。

核心代码

Markdown 渲染只需要几行:

use pulldown_cmark::{Options, Parser, html};

fn md_to_html(md: &str) -> String {
    let opts = Options::ENABLE_TABLES
        | Options::ENABLE_STRIKETHROUGH
        | Options::ENABLE_TASKLISTS;
    let parser = Parser::new_ext(md, opts);
    let mut html_out = String::new();
    html::push_html(&mut html_out, parser);
    html_out
}

代码高亮用 include_str!() 把 highlight.js 直接嵌进二进制:

const HLJS_JS: &str = include_str!("../assets/hljs/highlight.min.js");

这样完全离线可用,不依赖任何 CDN。

体积优化

Cargo.toml 里的 release profile:

[profile.release]
opt-level = "z"     # 优化体积
lto = true          # 链接时优化
codegen-units = 1   # 单线程编译,更好优化
strip = true        # 去掉调试符号
panic = "abort"     # 不要 unwind 代码

最终体积:

  • 单架构:1.1MB
  • Universal Binary(arm64 + x86_64):2.2MB
  • DMG 安装包:1.2MB

对比

MD PreviewElectron 方案
二进制~1.1MB150+ MB
内存~15MB200+ MB
启动秒开2-5 秒
运行时系统 WebView打包 Chromium

功能

  • 拖放 / Cmd+O / 命令行打开
  • 文件修改自动刷新
  • 40+ 语言代码高亮(离线)
  • 暗色模式跟随系统
  • GFM 表格、任务列表、删除线
  • macOS 双击 .md 文件关联打开

开源

MIT 协议,欢迎 Star 和 PR。


如果你也受够了臃肿的 Markdown 工具,试试这个 1MB 的方案。