每天肝到晚上两点,WYSIWYG 开源编辑器,正式启程

241 阅读6分钟

工作这几年来,个人最烦的几件事:

  1. WPS 提示某项功能需要会员
  2. WPS 编辑PDF需要会员
  3. 微信公众号、知乎、掘金、Notion、AFFiNE、Meduim、Dev.to 复制文章内容基本不兼容,你想要多个平台发布得重新写好几遍,累死,烦死

因此,大部分作者只能选择某一个平台做为主力,其他平台能照顾一下就勉强照顾一下,实际上无法分心。

个人在Notion,AFFiNE上也存了很多文章,最近非常想要搬出来和大家一起讨论交流,但这些平台的功能过于强大,导致导出的内容在其它平台很难兼容、很难保持足够的表现力。

因此,我萌生了一个自己制作编辑器的想法,目标是复制导出到各个平台要尽可能的能保持样式(主要是微信公众号平台、掘金和知乎),同时,编辑器能尽可能HTML5友好,这样,可以同时用于邮件编辑,也更容易导出Word和PDF,后期做PDF编辑器也能更有机会,尝试性地对某些公司“以下犯上”

项目进展(最小原型可用)

image.png

距离第一次提交(2024-10-18)接近1个月了, 目前静态文档的路线走通了,已经具备了替代Markdown做为编辑器的能力 尝鲜 github.io demo

  1. 基本的Marks标记,字体,inline样式支持,CodeBlock(基于Shiki),List,Table
  2. 项目支持通过github actions部署到github pages
  3. Dev Mode下支持保存内容到本地文件(vite middleware mode + express 做的临时api)
  4. 没有layout block,暂时用的table布局(而且后续email编辑器也是要用table布局的)
  5. 资源动态切换和文档目录支持(简易的)

最后两个周赶进度没有对微信公众号进行兼容测试,但是目前大部分内容可以直接复制过去,README.md里有一个兼容性支持表格(还待测试和优化)

first-view.png

first-view2.png

项目小目标

如开头所说,这个编辑器的目标是尽可能地支持内容可以兼容复制到其它平台发(至少微信公众号、掘金、知乎),所以:

  1. 首要目标:友好的交互,无bug,能做为富文本编辑器集成到其它项目
  2. 支持复制、导出Markdown;
  3. 更友好的HTML5,支持富文本编辑器间无缝复制,包括Word,PDF;
  4. 更友好地兼容邮件格式;

由于这个项目开源用爱发电,目前还有个人的小目标分:

  1. 服务于个人的博客笔记系统,邮件发送
  2. 支持更高级的内容(Live Playground), CodePen, Video块,支持MDX(以插件形式引入JSX组件等)
  3. 服务器缓存和RAG优化

这些都会开源,但是个人小目标会先闭源一段时间再开放。

下一步(近期规划)

自用编辑一段时间,实际体验下来对编辑器进行优化,编写开发心得。

项目希望更多伙伴参与进来,提提issue,使用建议,想要什么功能什么的,参与代码编写暂不乐意(因为我现在的时间大部分是22:00 到 2:00,没办法好好交流,只能个人快速迭代开发)。

目前编辑器在可用前还存在一些小毛病:

  1. 快捷键未阻止被浏览器捕获,或未生效的情况;(交互不够友好)
  2. 选中状态不明确(分割线、图、代码块),没有明显选中状态,对复制粘贴、删除不够友好
  3. 代码块的操作toolbar没做出来,就个人知道快捷键能用
  4. 测试微信公众号、掘金、知乎的复制粘贴兼容性
  5. 全面检查重构以支持完美的markdown导出

项目的技术路线, Why?(TL;DR)

目前编辑器的demo使用的是Svelte 5, But Why Svelte?

  1. 对于输出目标是原生JS的插件,Svelte的产物不但极其的精小,同时让你有非常棒的(框架)开发体验。

编辑器的目标本就是为了集成到框架无关的项目,正好;
同时,基于ProseMirror的Tiptap框架,使用Svelte编写Node-View插件定制高级块时,能从精小的产物上获益。

之前给公司的Sphinx — Sphinx documentation文档加过mermaid-js/mermaid 图的操作按钮(如下图),实现github markdown类似对“图”的操作,并且升级了对所有svg图片支持这些操作。

image.png

使用Svelte下来结果非常满意,甚至震惊到我,这个原生js插件用到了一个panzoom库(压缩下12KB),在包含svelte组件的前提下,整个功能17KB,也就是说Svelte的业务代码不到5KB,在你不能在某些平台使用Module Federation的使用,Svelte就是最佳的解决方案。

image.png

  1. 无状态的Svelte组件几乎接近web comopnents的复用体验(我为我说的话负责),组件迁移到其它框架更加简单(因为功能更少😂,对于我想要快速进行原型验证非常重要,同时编辑器组件已经定好了要用Svelte)

目前项目中的svg icon经过手动编辑调整大小、优化,只要删除svelte继承语法{...$$props}就能直接当svg资源用,别人想要用这套图标复制粘贴更方便

// SvgXXX.svelte
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24" {...$$props}>
    <path fill="currentColor" d="m7 10l5 5l5-5z"/>
</svg>

非编辑器的业务部分不用Svelte, Why?

此demo使用的Svelte,但是后续的编辑器业务部分(资源、保存、桌面程序、SSR)等都不会使用Svelte,why?

首先,不管是React Nextjs、Remix,Vue Nuxt,Angular17(的SSR混合渲染)他们相较于Svelte都有更成熟稳定的技术以及完全成熟稳定的UI框架,我不需要再通过shadcn-ui自己改来改去(是的,我对shadcn-ui的体验不佳)。

Svelte具备实现功能的能力,但在实现用户交互体验优化上,Svelte的生态很惨,我需要费很大劲去优化。 举个例子,我希望我的icon button,checkbox具有比看起来小图标更大的点击范围(Material Design的按钮规范),这可以让用户更轻松的点击、触摸到对该功能进行交互,如果有友好的动画就更好了。

image.png

好的UI库会在这些细节上征服开发者。所以,我大概率会使用: React + Mui + Remix

如果Remix在后续调研中不适合在 self-hosted 服务器版本、Cloudflare Workers上复用的话,就再改。

桌面程序使用Tauri,Why?

目前我个人不担心开发的电脑会出现Webview2不兼容缺失或者其它什么情况,选Tauri的目的很简单,我可以复用内置的Sqlite能力,如果后续要做多人协作或者处理多窗口冲突,需要一个本地(offline)下的快速存储内容的介质,目前Sqlite有Web端WASM版本,使用体验不错,支持虚拟文件系统(VFS)对于后续功能扩展也很灵活。

总结一下

如果进度乐观,未来的两到三个月之内,将发布体积小巧、原生JS友好的WYSIWYG富文本编辑器, 同时,一个简洁风格的开源博客系统(仅支持自部署),期待一下吧。

Tiptap的开发心得也会逐步编写发布到github pages, star关注一下吧。

求个Star,欢迎过来提需求,但暂不支持PR。

github: github.com/aolyang/tip…
playground: aolyang.github.io/tiptap-cont…