wangEditor | 项目复盘

2,503 阅读5分钟

楔子

自从加入 wangEditor 团队已有大半年了。

wangEditor V4 版本也已经越来越趋于稳定了。

目前也因为一个任务,让我想要对目前的 wangEditor 做一个整体复盘。

一、项目介绍

wangEditor 是一款 TypeScript 开发的 Web 富文本编辑器。

主打 轻量、简洁、易用

目标是 争做国内使用体验Z好的开源 Web 富文本编辑器!

我在 wangEditor 做过的事情

前期做过如下一些功能:

  1. 引用
  2. 插入视频
  3. 缩进
  4. 序列
  5. 多语言
  6. auto focus
  7. 丰富和优化内部核心模块的功能,例如: getNodeTop、getSelectionRangeTopNodes、prev、next、css 等等
  8. 以及若干 bug 和 测试

后期在 wangEditor 当中主要负责:

  1. issuesbug 的回复和收集
  2. 对已收集的 issuesbug 分门别类
  3. 进行任务的分配
  4. 参与 code review

二、项目背景

富文本编辑器所面向的业务场景有很多,例如:

  1. 留言板
  2. 邮箱
  3. 博客
  4. 新闻媒体
  5. 社区
  6. 贴吧
  7. 文档
  8. 资料库
  9. ...

这些场景都有一个共同点,那就是 所见即所得

这也是富文本编辑器所解决的业务痛点。

实际上开发一个简易的富文本编辑器相当的简单,只需要你简单的了解 contenteditable、execCommand、Selection、Range 的使用,就能快速的开发出一个简单的富文本编辑器。

当然该编辑器还存在着很多的问题,例如 execCommand 实际上在 MDN 上标记为已废弃

还有各个浏览器对 execCommand 的实现和支持各不相同,以及 execCommand 本身提供的能力也十分的简单。

所以开发一个简单的富文本编辑器虽然十分简单,但是要做一款优秀的富文本编辑器是相当之难的,需要处理各种各样匪夷所思的问题,而且 execCommand 所提供的能力也十分有限,所以很多的富文本编辑器都是抛弃了浏览器提供的 execCommand 转而研发自己的一套 execCommand,更甚者自主实现了富文本输入框,只依赖少数的浏览器 API

三、代码结构

该部分的内容可以在 wangEditorgithub 仓库中的 doc 目录下可以找到 doc

技术选型

wangEditor 本身不依赖任何框架

  • 使用语言:TypeScript
  • 打包工具:Webpack
  • 测试工具:jest、cypress

主要目录

  • .github/workflows github actions(持续集成)的配置文件
  • .vscode vscode 编辑器配置(推荐大家使用 vscode)
  • attachment 附件,和程序运行无关,但不可删除
  • build webpack 配置
  • dist 打包产出的目录。刚下载时没有该目录,本地运行 npm run build 即可生成
  • docs 开发文档
  • examples 本地测试用的 html 文件
  • server 服务端,用于联调图片或文件上传的功能
  • src 编辑器代码
  • test 单元测试代码
  • cypress E2E测试代码

Src 目录

  • wangEditor.ts 总入口
  • assets/ CSS 字体文件 图片
  • config/ 编辑器默认配置。配置项较多,所以按照分类拆分了多个文件。
  • editor/ 编辑器核心功能
    • index.ts 入口文件,产出编辑器的 class
    • change/ 编辑器 change 捕捉
    • disable/ 禁用编辑器
    • history/ 历史记录
    • init-fns/ 初始化的功能
    • upload/ 文件上传底层能力
    • z-index/ 层级
    • command.ts 封装 document.execCommand
    • selection.ts 封装 SelectionRange
  • lib/ 用到的第三方 js lib (无法通过 npm 安装的)
  • menus/ 菜单栏和菜单
    • index.ts 菜单栏 class
    • menu-constructors/ 生成单个菜单所用到的 class
    • menu-list.ts 汇总所有的菜单
    • 其他文件夹,具体的各个菜单,如 bold link
  • text/ 文本编辑区域
    • index.ts 入口文件,产出 class ,封装各个 API
    • event-hooks/ 初始化 text 的各个事件钩子,如回车、粘贴、删除时应该做哪些特殊处理
    • paste/ 处理粘贴事件
    • getChildrenJSON.ts 获取子元素的 JSON 格式数据
    • getHtmlByNodeList.tsnodeList json 格式中遍历生成dom元素
  • utils/ 工具
    • const.ts 常量
    • dom-core.ts DOM 操作的封装
    • util.ts 各个工具函数
    • custom-event 自定义事件
    • polyfill 兼容
    • data-structure/ 数据结构
    • observer/ 封装 MutationObserver

五、创建流程

编辑器的创建流程.jpg

六、菜单构造

菜单构造.png

七、结构关系

其实由下图可见,wangEditor 在不断的升级、迭代、修复中,已然开始有些杂乱了。

很多功能和模块都互相依赖非常的耦合在了一起,在修复 Bug 中也开始出现一些连锁反应,例如 A 修改了 Bug A,造成了 Bug B 的出现;B 修改了 Bug B,结果 Bug A 又死灰复燃了。

这也是我们编辑器急需突破和解决的问题,也是我做这一次复盘的主要原因 结构关系.jpg

八、总结思考

实际上目前我只是比较了解 wangEditor 一款富文本编辑器,对其他著名的富文本编辑器知之甚少,作为一名富文本编辑器的开发者而言这是不合格的,这方面我应该要去多多加强对富文本编辑器领域的深耕。

另外这段时间我其实在面试找工作,一方面是迫于生活的压力,一方面也是想寻求技术上的突破。同时在面试的过程中,以及在此次任务中时常有种无从下手的感觉,让我也了解到自己底子薄、思维定式、设计模式了解不深、基础知识欠缺、架构思维弱等等,所以还需加倍努力才行呀。

最后,如果你对富文本编辑器和开源项目感兴趣,欢迎加入我们 wangEditor 团队

本文正在参与「掘金 2021 春招闯关活动」, 点击查看 活动详情