我尝试自己构建 Markdown 编辑器(现实狠狠打脸)
Source: Dev.to
(未提供需要翻译的正文内容。如需翻译,请粘贴完整的文本。)
当我在 2024 年开始使用 daylog 时,AI 还没有今天这么聪明
当时没有“只要让模型生成一半编辑器”的快捷方式,所以大部分繁重的工作只能自己来。就在那时,我发现了一件事:
用颜色和样式制作文本编辑器比看上去要困难得多。
天真的开始
daylog 是一个支持 Markdown 的简易记事网页应用。至少,现在的定位仍然是这样。
一开始我想:“做一个带语法高亮的 Markdown 编辑器有多难?”
剧透 #1: 非常难(对我而言)。
基本上有三种实现方式:
- 使用已有的库。
- 使用普通的
<textarea>+ 预览窗口。 - 构建一个完全自定义的编辑器,在输入时实时高亮。
我一开始不想依赖现有库。想要完全掌控,所以选择了第 2 种方案:一个 <textarea> 加一个预览面板。
它能工作——而且对我的需求来说表现相当出色。
我从 GitHub Issues 与 PR 的编辑器中获得灵感:简单的 <textarea>、小工具栏、下面的预览。简洁且实用。
但使用自己的应用几个月后,我总觉得有什么不对劲。它显得……有点廉价。我想要更多的视觉反馈——能够即时看到粗体、标题、列表、任务项的效果,而不是只看到原始的 Markdown 符号。于是我决定升级。
“我就自己写个 Markdown 编辑器吧。”
是的,关于这点……
问题 #1 – <textarea> 的墙
HTML <textarea> 不支持 部分样式。你可以改变全部文字的颜色,但不能只给 粗体文字 或标题上色。
于是我尝试了一些 hack:
- 在
<textarea>上覆盖一个<div>。 - 隐藏真实内容。
- 改用
contenteditable。
这时事情开始变得混乱。
问题 #2 – 光标噩梦
在假高亮层和真实 <textarea> 之间同步光标非常痛苦:
- 选中文本?崩溃。
- 应用格式?错位。
- 快速输入?光标跳动。
使用 contenteditable 时,你必须手动管理选区范围、移动光标、重建文本节点,并且尽量不把一切都弄坏。
是可以做到的。但长期维护?那是另一回事。
问题 #3 – 性能现实检验
- 短笔记?没问题。
- 上千行的大文档?在每一次按键时运行正则解析 绝对 不行。输入延迟开始出现,没人愿意在键入后等上一秒才看到结果。这对写作工具来说是不可接受的。
当然,“笔记”本不该太大,但为什么要限制用户?有一次我不得不自问:我到底是在做记事本应用……还是代码编辑器?
Source: …
实现
经过一个月的挣扎、通宵和过量咖啡,我终于有了一个清晰的想法:我的目标从来不是构建一个文本编辑器引擎,而是构建 daylog。
于是我放下了“自己动手实现一切”的心态,开始寻找一个可靠的 Markdown 编辑器。
**剧透 #2:**这也并不容易。
Monaco:功能太强大反而成累赘
我想起了 Monaco——VS Code 背后的核心编辑器。听起来很完美,对吧?
可是……
- 起初很容易集成。
- 对于一个简单的笔记应用来说极其臃肿。
- 用普通 CSS 难以自定义。
- 移动端支持?不太理想。
- 移动端的光标和键盘行为?相当痛苦。
Monaco 确实很棒,但对 daylog 来说是大材小用……于是我继续寻找。
搜索过程
我尝试了几种方案:
- CodeMirror – 比 Monaco 更轻量,仍然功能强大。
- MDXEditor – 功能强大,但学习曲线更陡。
- react-simple-code-editor – 简单,但维护不活跃。
- @uiw/react-md-editor – 这个感觉与众不同。
胜者:@uiw/react-md-editor
我喜欢它的原因:
- 实现起来很容易。
- 可配置。
- 基于
<textarea>封装。 - 没有沉重的代码编辑器引擎。
- 支持 Mermaid、KaTeX 和 GitHub 风格的 Markdown。
- 可以通过 CSS 覆盖进行样式定制。
它与我最初的想法非常契合!
当我把它集成到 daylog 并添加一些自定义 CSS 调整后,一切终于顺畅起来:
- 编辑器外观良好。
- 响应速度快。
- 完全符合应用的定位。
最重要的是,我可以继续推进其他计划中的功能,并在 这里的 dev.to 页面 与大家分享,ofc!
我学到的
- 也许我太早放弃了自己构建编辑器的尝试……也许不是。
- 这本会是一次很棒的学习经历——绝对是。
- 它并没有与我的产品目标保持一致——并不完全是。
有时从零开始构建一切是出于自负。
有时是学习。
有时只是无谓的痛苦……(在我这里)。
如果你处在我的位置,你会怎么做?
你有没有曾经深入构建一些其实并非你的主要产品的东西?我很想听听你的故事。
如果你想查看代码,可以查看 daylog 仓库:
https://github.com/artifacts-oss/daylog
[https://github.com/artifacts-oss/daylog](https://github.com/artifacts-oss/daylog) 
