返回文章列表
1837 字 · 7 分钟

告别 Giscus:基于 Cloudflare Workers + D1 的博客评论系统自建与深度调优实践

· 编辑文章

引言:为什么放弃 Giscus?

在搭建静态博客时,基于 GitHub Discussions 的 Giscus 凭借零服务器运维、开箱即用的特性,成了许多开发者的首选。然而在实际运行中,有两个核心痛点始终难以解决:

  1. 读者门槛过高:每条留言都必须先登录 GitHub 账号。对于非程序员或路人读者而言,这一步阻断了大多数互动意愿。
  2. 多域名评论割裂:Giscus 依赖完整 URL 进行映射。如果博客同时绑定了多个自定义域名(例如主域名与备用域名),或者更换了访问入口,各域名之间的评论便无法互通,数据彻底碎片化。

为了彻底摆脱这两大限制,我选择迁移到开源的 CWD(Cloudflare Workers Discuss)。它依托 Cloudflare 全家桶(Workers + D1 + KV),兼顾了零服务器成本、免登录畅聊、以及基于文章路径(postSlug)的跨域名评论共享。

不过,官方默认组件在交互细节上较为粗放(强制填写邮箱、表单长期霸屏、点赞区域空白过大)。为此,我将官方仓库 Fork 到本地,进行了一次全链路自建与深度体验改造。本文将完整梳理这套方案的部署与落地细节。


一、后端部署与关键避坑

CWD 的后端非常轻量:以 Cloudflare Workers 作为 API 路由,D1 (SQLite) 存储评论与点赞,KV 缓存鉴权与后台配置。

1. 资源初始化

在本地利用 wrangler 创建所需基础设施并导入表结构:

# 创建 D1 数据库与 KV 命名空间
npx wrangler d1 create CWD_DB
npx wrangler kv namespace create CWD_AUTH_KV

# 初始化数据库结构
npx wrangler d1 execute CWD_DB --remote --file=./schema.sql

2. 规避 Workers.dev 1101 运行异常

在配置 cwd-api/wrangler.jsonc 时,如果直接发布到官方默认的 *.workers.dev 子域名,部分账户会在请求时遭遇 Error 1101: Worker threw exception。

根本解法:关闭 workers_dev,直接绑定独立的自定义域名:

// cwd-api/wrangler.jsonc
{
  "name": "cwd-api",
  "main": "src/index.ts",
  "compatibility_date": "2024-03-01",
  "workers_dev": false,
  "routes": [
    {
      "pattern": "cwd-api.yourdomain.com",
      "custom_domain": true
    }
  ],
  "d1_databases": [
    {
      "binding": "DB",
      "database_name": "CWD_DB",
      "database_id": "<your-d1-id>"
    }
  ],
  "kv_namespaces": [
    {
      "binding": "CWD_AUTH_KV",
      "id": "<your-kv-id>"
    }
  ]
}

3. 管理后台自托管(拒绝第三方中转)

CWD 官方文档推荐的后台是作者部署的托管页。出于数据主权与隐私安全考虑,管理后台必须完全私有化。

利用 Cloudflare Workers 的 Static Assets 能力,可以直接将后台(Vue 3 SPA)构建产物作为无服务器静态应用发布:

// cwd-admin/wrangler.jsonc
{
  "name": "cwd-admin",
  "compatibility_date": "2024-11-01",
  "assets": {
    "directory": "./dist",
    "html_handling": "single-page-application",
    "not_found_handling": "single-page-application"
  },
  "routes": [
    {
      "pattern": "cwd-admin.yourdomain.com",
      "custom_domain": true
    }
  ]
}

执行 pnpm build && npx wrangler deploy 后,即可拥有完全归属于自己域名的独立后台。


二、博客前端集成(Astro 场景适配)

在静态站点中接入动态评论区,重点在于生命周期管理与多域名数据一致性。

1. 静态产物本地化托管

拒绝直接引用 unpkg 或 jsDelivr 等外部公共 CDN,将构建生成的 cwd.js 统一存放在站点的 public/vendor/cwd-widget/ 目录下。既杜绝了外部 CDN 宕机导致评论瘫痪的风险,也能自主控制版本发布。

2. 跨域名点赞与 PV 数据归一

CWD 默认以 window.location.origin + window.location.pathname 作为点赞与 PV 统计的唯一键。为了避免多域名导致阅读计数分裂,在挂载前统一将请求地址重写为站点的 Canonical 域名:

// 归一化统计地址,多域名访问共享统一计数
const canonicalUrl = canonicalOrigin + window.location.pathname;

3. Astro 生命周期与暗黑主题同步

配合 Astro 的 View Transitions(ClientRouter),在 CwdComments.astro 中做好初始化与解绑:

  • 路由切换:监听 astro:before-swap 调用 unmount() 销毁实例,并在 astro:page-load 重新装配;
  • 明暗主题:通过 MutationObserver 监听 document.documentElement 的主题类变化,实时驱动 Shadow DOM 内的 data-theme 切换。

三、核心体验调优:针对官方组件的深度改造

官方组件在桌面端体验上稍显生硬,为此我基于 Fork 后的源码进行了针对性改造,作为可选开关向上兼容:

1. 邮箱必填改为选填

许多读者不愿意暴露真实邮箱。我们在前后端同步放宽了验证限制:

  • 后端放宽:修改 cwd-api/src/api/public/postComment.ts,邮箱允许传入空串;为空时跳过邮件通知逻辑,头像由服务端自动根据昵称首字母生成 SVG;
  • 前端适配:在 validator.js 中将提交按钮的激活条件收敛为仅依赖「昵称」与「评论内容」,多语言文案去掉邮箱后的必填星号。

2. 评论表单默认折叠(collapseForm)

默认展开的表单占据了大量垂直高度,在没有评论时尤其显得空旷。

我们在组件核心层增加了折叠交互:

  1. 首屏轻量展示:仅渲染一行精致的占位入口:[ ✏️ 写下你的评论... ] [ 写评论 ];
  2. 平滑展开与对焦:点击触发条后展开完整表单,并自动将光标聚焦到正文输入框;
  3. 适时智能收起:表单左下角提供「收起」按钮;在评论提交成功、或读者点击某条评论进行局部回复时,主表单自动折叠归位。

3. 紧凑单行点赞条(compactLikeBar)

官方点赞条采用了 32px 的大爱心竖向堆叠,加上 30px 15px 的外层边距,整块区域高达 154px,而内部文字和按钮实际只有 62px。配合折叠表单后,这片空白十分突兀。

我们在样式层将其重构为紧凑横向胶囊(高度降至 28px,爱心缩小为 20px),整体节省了 114px 的冗余空白,视觉比例自然利落。

4. 彻底解决卡片顶部 138px 空白与悬空虚线

完成上述调整后,页面依然存在一块奇怪的空白,中间还横亘着一条悬空虚线。

排查发现,这是旧版博客单列长页布局遗留下来的样式冲突:

  • 博客原版无卡片容器,旧代码在 .comments-section 上添加了 margin-top: 64px; padding-top: 48px; border-top: 1px dashed var(--border); 用于分割正文;
  • 改版为 Bento 风格后,评论区已被整体放进 <div class="fuwari-card p-6"> 卡片中;
  • 继承的旧样式在卡片内部又塞入了 64px 外边距与 48px 内边距,硬生生顶出了一片 138px 的空白与多余虚线。

解法:在 CwdComments.astro 中将 .comments-section 的上外边距与虚线彻底归零:

.comments-section {
  margin-top: 0;
  padding-top: 0;
  border-top: none;
}

.comments-header {
  margin-bottom: 24px;
}

调整后,评论区标题自然顶格对齐,与卡片标准的 24px(p-6)内边距完全呼应。


四、方案总结与落地效果

维度迁移前 (Giscus)改造后 (CWD 深度定制版)
读者门槛必须拥有并登录 GitHub 账号完全免登录,填写昵称即可发布
多域名连通按页面完整 URL 隔离,互不互通按文章路径(Slug)统一聚合
表单占用强行展开大表单(>300px 高)默认单行折叠,点击按需展开并自动聚焦
点赞与留白竖排大爱心占用 154px 高度28px 紧凑小胶囊,无多余大片空白
基础设施依赖外部第三方服务全套 Cloudflare 免费 Serverless 自托管

通过这次改造,博客拥有了一个极低门槛、多域名无缝连通、视觉高度统一且完全私有可控的轻量评论系统。

参考

https://github.com/anghunk/cwd

标签: #前端

评论

无需注册,填写昵称即可评论 阅读 — 次