常看笔者博文的读者都知道,笔者的博客站点(zhen.wang)为了其简约性,一直以来都未直接集成评论能力,而是通过让读者通过跳转 GitHub 并提交 issue 方式来收集读者反馈。虽然这种方式可行,但实际上一点也不便捷。本月初的时候,收到一名读者的留言,希望对博客留言的方式进行优化。在对各种留言评论系统进行调研以后,笔者还是决定再造一造轮子。于是,笔者花了几天时间开发了 COME,一套能够自托管的,足够轻量的评论系统。
基本能力
COME主要有两个特点:
- 自托管
- 足够轻量
对于"自托管"来说,本系统主要借助Cloudflare提供的能力/服务,通过免费(一定额度)的 Worker 来承载评论系统的后台服务接口逻辑,通过 Cloudflare D1 轻量级数据库来存储所有的评论数据。
对于"足够轻量"来说,笔者在设计本系统时,整个系统只使用了一张数据库表来存储站点评论数据,不引入其他额外的复杂功能来增加本系统复杂度,以及开发心智负担,我相信任何感兴趣的朋友可以快速理解本系统,并搭建一套属于自己的评论系统。
就目前而言,本系统包含了以下功能:
-
一个基于包含preact运行时的轻量级客户端评论展现/提交组件(umd形式提供),ComeCommentBox。该组件使用 TypeScript + preact 进行开发,得益于 preact 的足够轻量级,ComeCommentBox 最终构建后产物(js+css)文件体积在 37 KB左右(包含preact运行时),通过简单的配置,可以轻松的嵌入挂载到任意Web页面上,加载并渲染相关的评论列表。
-
评论后台管理服务(基于Hono开发),以及后台管理Web页面(TypeScript + React + antd@5,开发中),用于管理留言评论:
-
评论审核(默认开启)。开启后,所有来自网友提交评论需管理者主动审核才能展现在客户端页面评论区。
-
评论移除。支持管理者手动删除某些留言评论。
-
一些技术细节
评论者身份认证问题
为了尽可能的轻量,本系统不支持评论者登录能力 (即没有身份验证)。评论者只需提供邮箱、昵称以及评论内容即可完成评论提交。对于用户邮箱地址隐私问题,后台服务不会存储真实的邮箱地址,而是在处理评论提交请求时,对邮箱地址进行脱敏操作(例如将 "abc@xxx.com"
脱敏为 "a***c@xxx.com"
),并只存储脱敏邮箱地址;当然,为了确定用户"唯一性",后台服务会使用通过MD5算法计算邮箱地址的摘要字符串作为用户id进行存储,以便识别"唯一"用户。至于有心之人冒充评论者的问题(比如用户A从别处知道了用户B的邮箱地址以及其评论昵称,进而在评论区冒充用户B发言),本系统暂不考虑应对措施,可交给使用本系统的开发者用户自行拓展能力。
当然,为了评论区的合法性,笔者强烈建议开启评论审核能力,主动规避剔除一些垃圾评论。
COME仓库解读
COME使用pnpm monorepo方式组织管理项目代码。该仓库下主要包含以下几个模块:
-
公共类型定义(packages/common-types目录)。该模块仅提供TypeScript类型定义,方便后台服务、前端页面组件共享类型定义。
-
评论系统接口服务(packages/server目录)。基于Cloudflare Woker的node服务,使用TypeScript开发,整个服务目前只有3个依赖库:
- Hono:与Cloudflare深度集成的超轻量级 Web 框架。高性能,零依赖。
- drizzle-orm:Cloudflare 生态中用于类型安全数据库操作的轻量级 TypeScript ORM 库,尤其与 Cloudflare D1(边缘 SQLite 数据库)深度集成
- zod:一个高性能,轻量级的校验库。可以方便定义一些数据的字段校验规则。
-
后台服务管理WebUI(packages/web-server-management)。后台服务的Web页面,核心使用React+antd@5开发。通过该Web系统,可以方便的管理站点系统的所有评论留言。
-
客户端评论UI组件 ComeCommentBox(packages/come-comment-box)。TypeScript + preact 进行开发,只依赖preact。
更多内容
COME的开发虽然快接近尾声,但由于本月笔者事务繁多,时间有限,COME还在有一些事项未彻底完成。笔者计划8月底之前完成COME系统套件的研发收尾、文档编写(包含功能介绍,开发调试)工作。届时发布相关的动态,以及再次更新本文内容,还请各位读者多多关注!