从“想做一个 Craft”到 ArkBlocks:一次 AI 协作开发原生 Block Editor 的心路历程
最开始,我只是想做一个类似 Craft.do 的笔记编辑器。准确一点说,我想在 HarmonyOS NEXT 手机上,用 ArkTS 原生开发一个真正好用的 Block Editor。不是 WebView,不是简单套一个网页编辑器,也不是把 React 生态里的东西硬搬到鸿蒙上,而是尽量用 HarmonyOS 自己的能力,做一个适合手机端使用的原生编辑器。刚开始的时候,这个目标听起来其实很大,也很模糊。Craft 很好看,交互也很舒服。它的文档、卡片、折叠、拖拽、内联样式、图片排版都很迷人。但如果真的要自己做,问题马上就来了:一个 Block Editor 到底应该怎么设计?它的 Document Model 是什么?Block 和 Inline 应该怎么组织?Undo / Redo 怎么做?拖拽怎么做?图片、卡片、Callout 这些能力,是写死在编辑器里,还是做成插件?AI 能不能帮我把现有的开源编辑器,比如 BlockNote,迁移到 ArkTS?这就是整个 ArkBlocks 项目的起点。第一阶段:从“移植 BlockNote”到“理解编辑器”一开始,我的想法很直接:BlockNote 是开源的,能不能让 AI 去读它的源码,然后把它迁移到 ArkTS?这个想法很自然,但后来我们慢慢意识到,直接“迁移”不是最好的路。BlockNote 的实现依赖 React、Tiptap、ProseMirror、DOM、Selection API、contenteditable 等一整套 Web 体系。HarmonyOS NEXT 是另一套世界。ArkUI 有自己的声明式 UI,RichEditor 有自己的输入机制,鸿蒙的手势、键盘、剪贴板、生命周期也都和浏览器不一样。所以我们逐渐把目标从:迁移 BlockNote调整成:学习 BlockNote 的架构思想,然后为 HarmonyOS 重新设计一个原生 Block Editor Framework。这一步非常关键。它让项目不再是“翻译代码”,而是进入了“抽象设计”的阶段。我们先让 AI 阅读 BlockNote,输出了几份研究文档:Editor ArchitectureDocument ModelEditor Design Principles这些文档不是为了抄代码,而是为了回答几个根本问题:为什么现代编辑器要用 Block?Document、Block、Inline、Style、Selection 之间是什么关系?哪些是平台无关的核心能力?哪些是浏览器环境下的实现细节?如果换成 ArkTS,哪些东西应该保留,哪些东西应该重新设计?这一步之后,我开始意识到:真正值得做的不是一个“鸿蒙版 Craft”,而是一个 HarmonyOS 原生 Block Editor Framework。后来这个项目就有了名字:ArkBlocks第二阶段:先做架构,而不是急着写代码很多 AI Coding 项目容易犯一个错误:刚想清楚一点方向,就立刻让 AI 写代码。我们这次反而刻意踩了刹车。先建立了 AGENTS.md,让所有 AI 知道这个项目是什么,不是什么。ArkBlocks 不是一个普通笔记 App,而是一个可复用的编辑器框架。然后建立了 docs/research、docs/design、docs/rfc、docs/spec、docs/tests 等文档体系。当时我们做了几件现在回头看非常有价值的事情:1. 架构设计我们让 AI 设计了 ArkBlocks 的总体架构,明确了:DocumentBlockInlineSelectionTransactionHistoryCommandRendererAdapterRuntime这些模块之间的关系。2. RFC我们建立了 RFC-0001:Document Canonical Model。这份 RFC 冻结了整个项目最重要的决策:Document Block Tree 是 ArkBlocks 的唯一真相来源。也就是说:Renderer 不拥有文档状态Selection 不复制文档内容History 不直接持有活动 Block 对象所有修改都必须通过 TransactionDocument Tree 是整个编辑器的核心数据结构3. SPEC后来我们又做了 SPEC-0001:Document Operations Specification。这份文档详细定义了:InsertBlockDeleteBlockMoveBlockDuplicateBlockSplitBlockMergeBlockReplaceBlockInsertInlineDeleteInlineUpdatePropsIndentOutdent每一个操作都要说明前置条件、输入输出、状态变化、Selection 行为、History 行为、失败条件和复杂度。4. SPEC Test之后我们又写了 SPEC-0001-Test-Suite,把行为规范转成测试用例。这一步很重要。因为它让项目不只是“文档说得漂亮”,而是开始有了可验证的契约。从现在看,这套流程非常像大型框架项目:Research ↓ Architecture ↓ RFC ↓ SPEC ↓ SPEC Test ↓ Implementation ↓ Code Review这和普通的“让 AI 写功能”完全不同。第三阶段:从骨架工程到真正可运行有了架构之后,我们开始让 AI 搭建 Framework Skeleton。这个阶段不是为了实现功能,而是为了把架构变成真实的代码结构。AI 创建了大量模块:core/typesschemadocumenttransactionhistorycommandrendereradapterplugineditor一开始这些模块很多只是接口、空实现、TODO,但它们的意义很大:AI 后面写代码时,不再凭空发明架构,而是在既有框架里补实现。之后我们开始真正实现 Document Index System,也就是 PR-0001。这个 PR 解决了一个非常关键的问题:Block 查找必须是 O(1)。如果每次编辑都递归遍历整个 Block Tree,编辑器以后一定会在大文档里崩掉。所以 Document 维护了:blockIndexparentIndex这一步看起来很底层,但它奠定了整个编辑器的性能基础。PR-0001 之后我们还做了 Code Review,发现了 Transaction 原子性、索引外部可变等问题,于是又做了 PR-0001A 修复。

相关新闻