博客评论系统迁移记:Valine → Waline → Twikoo(附评论系统对比与 Cloudflare Workers + D1 部署教程)

博客评论系统迁移记:Valine → Waline → Twikoo(附评论系统对比与 Cloudflare Workers + D1 部署教程)

💡 原文中文,约23900字,阅读约需57分钟。
📝

内容提要

作者因LeanCloud停服和Vercel账号被封,将博客评论系统从Valine、Waline迁移至Twikoo+Cloudflare Workers+D1,536条评论无损迁移且零成本。文中对比十款评论系统,详述部署步骤、配置要点及数据转换中的路径编码、表情短码、超长内容等问题,并强调免费PaaS不可靠,应定期备份并监控评论区。

🔎

延伸解读

免费PaaS的隐性风险:账号封禁与静默失效

作者的经历揭示了免费PaaS的两个关键风险:一是账号可能因不明原因被封(如Vercel返回451),且无解释;二是服务失效时前端可能无显眼报错,导致评论区挂掉一个多月才被发现。这提醒我们,依赖第三方免费服务时,需建立监控机制(如定时请求接口),并定期检查服务状态,不能假设其永远可用。

数据迁移中的技术细节:路径编码与内容格式

迁移536条评论时,作者遇到多个技术坑:Valine存储解码后的路径,而Twikoo使用编码后的location.pathname,导致中文路径评论不显示;早期Valine存HTML,后期存Markdown,需统一渲染;表情短码需映射为图片。这些细节说明跨系统迁移不能只导数据,还需处理格式差异,否则评论可能“消失”或显示异常。

Twikoo + Workers + D1的适用性与限制

该方案适合域名已托管在Cloudflare、需要匿名评论且读者在国内的个人博客,免费额度足够。但有限制:必须绑自定义域名(workers.dev被污染);无法直连SMTP,邮件需走HTTP API或改用Telegram;Cloudflare版缺少Akismet和腾讯云内容安全,反垃圾依赖频率限制、验证码或人工审核;批量导入时需注意D1的查询次数和CPU限制。

评论系统选型的关键考量

作者对比十款系统后给出建议:Valine因LeanCloud停服应尽快迁出;Waline功能最全但Vercel部署国内访问差;Twikoo部署方式多且国内友好;Artalk适合有服务器的用户;Giscus适合读者有GitHub账号的技术博客;Disqus国内基本不可用;Cusdis已停止维护。选型需综合考虑数据主权、访问速度、功能需求和维护成本,避免选择已停更或即将停服的项目。

❓

Q&A

为什么作者最终选择 Twikoo + Cloudflare Workers + D1 作为评论系统?

作者选择该方案主要基于三点:一是评论后端放在自己本来就离不开的平台上(博客 DNS 已托管在 Cloudflare),避免依赖额外的免费 PaaS;二是 Workers 和 D1 的免费额度对个人博客足够,成本为 0 元;三是 Twikoo 2.x 有官方的 Cloudflare Workers + D1 适配器,且 Butterfly 主题原生支持,支持匿名评论和内嵌管理面板。

Valine 评论系统存在哪些主要问题,为什么必须迁移?

Valine 完全依赖 LeanCloud,而 LeanCloud 已公告将于 2027-01-12 正式停止全部对外服务,届时数据会被永久销毁或匿名化。此外 Valine 本身已停更(最后版本 v1.5.3 发布于 2024-12),邮件提醒和验证码功能早已废弃。更严重的是,Valine 前端直连 LeanCloud,AppKey 公开在页面中,任何人可通过 REST API 读取整张评论表,包括评论者的邮箱和 IP。

迁移过程中遇到了哪些数据转换问题,如何解决?

主要问题包括:①路径编码不一致(Valine 存解码路径,Twikoo 用编码后的 location.pathname),用 encodeURI(decodeURI(url)) 统一;②内容格式混杂(HTML 与 Markdown 混排),用 marked 渲染并去除回复前缀;③Valine 表情短码(如 :doge:)不被 Twikoo 识别,映射为图片地址;④评论中 base64 截图过大,单条 INSERT 超 100 KB 限制,采用先插入空记录再分段 UPDATE 追加;⑤SQL 转义用 CAST(X'...' AS TEXT) 避免引号换行问题;⑥楼中楼关系需正确映射 pid 和 rid,并处理父评论已删除的断链情况;⑦时间戳统一为毫秒;⑧博主标记和头像字段处理,避免泄露 QQ 号。

Twikoo + Cloudflare Workers + D1 方案有哪些限制或代价?

该方案的主要限制包括:需要自己从源码构建(适配器未发布到 npm,要求 Node.js 26 和 pnpm 12.5.1);Workers 上不能直连 SMTP,邮件只能走 HTTP API(如 Resend)或改用 Telegram 推送;Cloudflare 版不支持 Akismet 和腾讯云内容安全,反垃圾只能靠频率限制、验证码、违禁词、人工审核或 AI 检测;workers.dev 域名在国内被 DNS 污染,必须绑定自定义域名;免费版有 10 ms CPU 时间和每次调用查询数限制,批量导入大量评论有风险。

如何将旧评论数据导入 Twikoo + D1?

作者没有使用后台导入功能,因为 D1 免费版每次调用查询数有限(约 50 次),且数据格式问题多。做法是:在本地用 Node.js 脚本将 LeanCloud 和 Neon 导出的数据转换为 SQL 文件,处理路径编码、Markdown 渲染、表情短码、超长内容分段等;先用 wrangler d1 execute --local 导入本地模拟库检查数量和回复关系,确认无误后再用 --remote 导入线上库。导入时使用 INSERT OR IGNORE 以便重跑,超长评论先插入空记录再分段 UPDATE 追加。

部署 Twikoo 到 Cloudflare Workers 时有哪些常见坑?

常见坑包括:pnpm install 报 Node 版本不符(需 Node 26);管理面板提示前后端版本不一致(构建前需执行 release-set-version.mjs);升级时版本脚本报基线校验失败(需先 git checkout -- . 还原);部署报错 code 100117(需删除旧的 Vercel CNAME 记录);配了 routes 后 workers.dev 地址不可用(需显式设 workers_dev = true);不加 --remote 时线上库没有表;切换评论系统后页面仍显示旧系统(Hexo 配置合并数组去重追加,需同时改主题自带 _config.yml);部署后访客看到旧评论区(Cloudflare 缓存 HTML 5 小时,需 Purge Everything);收不到邮件通知(Workers 不能直连 SMTP,需用 HTTP API 或 Telegram)。

作者从这次迁移中总结了哪些经验教训?

主要教训有:免费 PaaS 账号说没就没且可能无解释,评论后端应放在自己本来就离不开的基础设施上,且不要与其他高风险项目混用同一账号;要把部署信息(域名指向、数据库位置、登录方式)写下来,避免遗忘;定期导出备份,不要依赖运气;前后端版本要锁定且一致,注意主题配置合并行为,切换后清 CDN 缓存;给评论区加监控(如 UptimeRobot 或 Workers Cron),因为推送只能通知新评论,后端挂了不会报警。

🏷️

标签

➡️

继续阅读