跳到主内容

PRJ-05 LIVE

PDF2MD 浏览器端 PDF 转 Markdown

browser-only pdf to markdown, zero backend

拖入 PDF 秒出 Markdown,文件不出本机、断网可用

  • 前端
  • TypeScript
YEAR
2026
ROLE
独立开发 · 产品设计
STATUS
LIVE
TIER
项目

~120ms

8 页文档转换耗时(WASM 引擎,无服务器往返)

0 次

网络请求 / 埋点 / 第三方脚本——文件全程不出本机

0.875

同源引擎在 opendataloader-bench(200 份真实 PDF)的 Overall 得分

24 项

Playwright 端到端断言(Chromium + Firefox 实测)

// 01

问题背景

把 PDF 喂给 LLM 前的第一步永远是「转 Markdown」,但主流方案要么要装 Python 环境(pymupdf4llm / markitdown),要么得把文件上传到别人的服务器——对包含简历、合同、论文的 PDF,上传本身就是不可接受的风险。

PDF2MD 想验证一个判断:WASM 已经足够快,「上传 → 排队 → 下载」的服务器模式在文档解析场景完全可以被纯前端取代,隐私与速度可以兼得。

// 02

系统架构

界面层

React 状态机驱动的单页应用

Dropzone(点击 / 拖拽上传,上限 50MB)App 状态机:idle → ready → converting → done / errorResultView 双栏:Markdown 源码(rehype 高亮)+ GFM 渲染预览SettingsPanel:页码标记 / 紧凑模式 / 选页转换(如 1-3,5)

桥接层

主线程与 Worker 之间的 Promise 化协议

useConverter:Worker 调用的 Promise 封装(id 映射)postMessage 传递 Uint8Array(transferable 零拷贝)Worker 就绪后惰性预热引擎

解析层

独立 Worker 沙箱内的 WASM 引擎

@firecrawl/pdf-inspector-wasm(Rust → WASM,MIT)processPdf(bytes, opts) 输出结构化 MarkdownCMap 内嵌,CJK 字体零配置多栏排版阅读顺序识别

// 03

关键技术决策

每一条都包含「为什么这样选」与「代价是什么」——这是我理解这个项目的方式。

纯浏览器 WASM 方案,彻底砍掉后端

服务器方案的隐性成本:上传带宽、排队延迟、隐私合规、服务器账单。WASM 方案把这一切归零,还附赠「断网可用」。代价是首次要加载约 5MB 引擎(gzip 后约 2.3MB)——用 Worker 惰性预热与静态缓存对冲;另一个代价是无法做大文件流式解析,50MB 上限是务实取舍。「零后端」从第一天就是设计约束而不是宣传点,后续所有选型都由它推出。

选 pdf-inspector WASM 而非 pdf.js 自研排版还原

自研「文本块 → 标题 / 列表 / 表格」的排版还原是无底洞。直接采用经过审计的开源 Rust 引擎——同源内核在 opendataloader-bench 上 Overall 0.875、200 份文档总耗时 0.470s,比 pymupdf4llm 快一个数量级以上——自己专注产品层。代价是解析质量受制于上游,扫描件 OCR 需要另接 tesseract.js(已列入 Roadmap)。

Web Worker + transferable,主线程零卡顿

PDF 解析是 CPU 密集任务,放主线程会冻结 UI——页面无法滚动、按钮没有反馈、用户以为程序死了。解析跑在独立 Worker,字节流用 transferable 零拷贝传递,useConverter 把 postMessage 协议封装成 Promise。代价是调试链路变长、引擎冷启动要预热管理,但换来转换过程中界面完全可交互。

紧凑模式:为 LLM 场景优化 token 消耗

目标用户大量是「转完喂给 LLM」的开发者,Markdown 的冗余空白直接等于 token 成本。高级设置里提供紧凑模式(更精简输出)、页码标记(便于溯源引用)、选页转换(只要第 1-3,5 页)。功能小,但精准打在真实工作流上。

// 04

我的职责与产出

RESPONSIBILITIES

  • 设计纯前端零后端的产品形态与隐私架构
  • 实现 Worker Promise 化桥接与 transferable 零拷贝传输
  • 实现 React 状态机 UI 与双栏结果视图(源码高亮 + GFM 预览)
  • 实现高级设置:页码标记 / 紧凑模式 / 选页转换
  • 编写 24 项 Playwright 端到端断言并接入验证流程
  • 部署 Cloudflare Pages(push main 自动发布)

OUTCOMES

  • 8 页文档转换约 120ms,全程 0 网络请求,断网可完整使用
  • 结构化输出覆盖 H1–H4 / 列表 / 代码块 / 表格 / 加粗斜体 / 链接
  • CJK 与多栏阅读顺序开箱可用,无需任何配置
  • 纯静态站点一键部署至 Cloudflare Pages,无服务器成本

// 05

踩坑与复盘

这个项目验证了「小工具也值得完整工程化」:e2e 断言、状态机 UI、零依赖打包一个没少。最大的边界是扫描件——文本型 PDF 解析得再快,图片型 PDF 也只能提示「需要 OCR」。tesseract.js 集成、内嵌图片提取与批量文件队列都在 Roadmap 上。

// 06

技术栈

  • React 19
  • TypeScript
  • Vite 8
  • Tailwind CSS 4
  • WASM
  • Web Worker

视觉风格