惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

B
Blog RSS Feed
C
CERT Recently Published Vulnerability Notes
P
Proofpoint News Feed
Y
Y Combinator Blog
T
The Blog of Author Tim Ferriss
云风的 BLOG
云风的 BLOG
H
Help Net Security
Recorded Future
Recorded Future
The Register - Security
The Register - Security
F
Full Disclosure
N
Netflix TechBlog - Medium
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
酷 壳 – CoolShell
酷 壳 – CoolShell
H
Hackread – Cybersecurity News, Data Breaches, AI and More
爱范儿
爱范儿
Security Archives - TechRepublic
Security Archives - TechRepublic
Simon Willison's Weblog
Simon Willison's Weblog
Cisco Talos Blog
Cisco Talos Blog
I
InfoQ
T
Tenable Blog
T
Tor Project blog
人人都是产品经理
人人都是产品经理
D
DataBreaches.Net
NISL@THU
NISL@THU
Google DeepMind News
Google DeepMind News
博客园 - 叶小钗
B
Blog
V
V2EX
Jina AI
Jina AI
L
LangChain Blog
月光博客
月光博客
W
WeLiveSecurity
U
Unit 42
AWS News Blog
AWS News Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
博客园 - 聂微东
V
Visual Studio Blog
A
Arctic Wolf
T
Tailwind CSS Blog
The Cloudflare Blog
SecWiki News
SecWiki News
S
SegmentFault 最新的问题
Hacker News - Newest:
Hacker News - Newest: "LLM"
宝玉的分享
宝玉的分享
MyScale Blog
MyScale Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
S
Securelist
www.infosecurity-magazine.com
www.infosecurity-magazine.com
腾讯CDC
雷峰网
雷峰网

szhshp 的第三边境研究所

假设, AI 把我代替的那一刻真的到来 | szhshp 的第三边境研究所 小傻瓜都能懂的 AstrBot QQ 机器人集成 MCP 功能实战指南 | szhshp 的第三边境研究所 《智人之上: 从石器时代到 AI 时代的信息网络简史》阅读笔记 | szhshp 的第三边境研究所 iPadOS 26 无法设置空间场景图片壁纸的解决方法 | szhshp 的第三边境研究所 《一路云海》(终) | szhshp 的第三边境研究所 《一路云海》(四): 如何不按套路旅行 | szhshp 的第三边境研究所 《一路云海》(三): In Ya Mellow Tone | szhshp 的第三边境研究所 《一路云海》(二): 关西世博参观纪实 | szhshp 的第三边境研究所 《一路云海》(一): 新的征程 | szhshp 的第三边境研究所 2025 大阪世博会 [ 3 天前-先到先得 ] 阶段 场馆预约必中独家攻略 | szhshp 的第三边境研究所 Hackathon 随想 | szhshp 的第三边境研究所 一杯双皮奶 | szhshp 的第三边境研究所 Armbian + CasaOS + NAS 配置指南 | szhshp 的第三边境研究所 Docker 构建镜像报错: error getting credentials - err: exit status 1, out: `` | szhshp 的第三边境研究所 炸弹猫桌游变体规则 | szhshp 的第三边境研究所 《小岛经济学》阅读笔记 | szhshp 的第三边境研究所 《金钱心理学》阅读笔记 | szhshp 的第三边境研究所 为知笔记 RIP: 迁移剩余的笔记 | szhshp 的第三边境研究所 2025 博客第十年展望 - 再见我的过去 | szhshp 的第三边境研究所 我在独立游戏里面致敬的作品 | szhshp 的第三边境研究所 《How to make thing faster》阅读笔记 | szhshp 的第三边境研究所 《The Art of Clean Code》阅读笔记 | szhshp 的第三边境研究所 《Clean Architecture: A Craftsman Guide to Software Structure and Design》阅读笔记 | szhshp 的第三边境研究所 《How AI Works》阅读笔记 | szhshp 的第三边境研究所 游戏策划废案 - Project Uranus | szhshp 的第三边境研究所 游戏策划废案 - Project X | szhshp 的第三边境研究所 人生第一款独立游戏开发复盘 | szhshp 的第三边境研究所 Trap of Life | szhshp 的第三边境研究所 如果我用手搓了个暗物质雏形 | szhshp 的第三边境研究所 《Rust Programming Language》- EX - Cheatsheet | szhshp 的第三边境研究所 新的播放器上线了 | szhshp 的第三边境研究所 Cypress - End-to-End Testing: OKTA Authentication with MFA | szhshp 的第三边境研究所 VSC x VIM - 反正多学几个快捷键没有坏处 | szhshp 的第三边境研究所 两小时 Docker 速成 - Getting Started | szhshp 的第三边境研究所 《The Joy of Javascript》- 5 - Data | szhshp 的第三边境研究所 《The Joy of Javascript》- 4 - Meta Programming | szhshp 的第三边境研究所 《The Joy of Javascript》- 3 - ADT(Algebraic Data Type) | szhshp 的第三边境研究所 Web-Automation Testing | szhshp 的第三边境研究所 《The Joy of Javascript》- 2 - Functor/Monad | szhshp 的第三边境研究所 《The Joy of Javascript》- 1 - Object/Function | szhshp 的第三边境研究所 EvalError: Possible side-effect in debug-evaluate | szhshp 的第三边境研究所 前端 QA 工具链指南 - husky,commitlint,commitizen,eslint,typescript,express | szhshp 的第三边境研究所 效率工具 & 软件推荐 | szhshp 的第三边境研究所 站点开源 Project Titan | szhshp 的第三边境研究所 cmd/powershell-命令速查-Cheatsheet | szhshp 的第三边境研究所 Git-命令速查与相关问题解决-Cheatsheet & Troubleshooting | szhshp 的第三边境研究所 Tailwind.css not included in NextJS Production | szhshp 的第三边境研究所 Github GraphQL API - Data Integration | szhshp 的第三边境研究所 尝试 Windows Terminal + z.lua | szhshp 的第三边境研究所 StrokePlus.net - Powerful Hotkey Boost | szhshp 的第三边境研究所 优雅地 Hack 一台黑苹果 | szhshp 的第三边境研究所 一杯关东煮 | szhshp 的第三边境研究所 Gitee x PicGo 管理图床 | szhshp 的第三边境研究所 Create Your Own Redux (Typescript) | szhshp 的第三边境研究所 Getting Started: Ionic + Capacitor + React + Typescript + Android | szhshp 的第三边境研究所 GraphQL: File Upload & Troubleshooting | szhshp 的第三边境研究所 吉祥航空随心飞刷票工具循环查票工具 | szhshp 的第三边境研究所 NVM Windows Portable Installation | szhshp 的第三边境研究所 NextJS x Typescript - Integration & Troubleshooting | szhshp 的第三边境研究所 全站点升级 - Project Titan | szhshp 的第三边境研究所 AWS-EC2-常见问题解决-Troubleshooting | szhshp 的第三边境研究所 Workbox-Getting Started | szhshp 的第三边境研究所 《时间简史》阅读笔记 | szhshp 的第三边境研究所 《时间的秩序》阅读笔记 | szhshp 的第三边境研究所 ESLint-常见问题解决-Troubleshooting | szhshp 的第三边境研究所 站点索引 | szhshp 的第三边境研究所 个人知识库搭建 - Hexo 实现 Github/Coding 持续集成 | szhshp 的第三边境研究所 BMOB-常见问题解决-Troubleshooting | szhshp 的第三边境研究所 React + Typescript: 开启 HMR/Hot Loader | szhshp 的第三边境研究所 Yarn & NPM | szhshp 的第三边境研究所 ESLint: Typescript + React + TSX 集成 | szhshp 的第三边境研究所 《10101》EP15:过年 2020 | szhshp 的第三边境研究所 Cmder-Usage | szhshp 的第三边境研究所 Redux-DOM not refreshed | szhshp 的第三边境研究所 React Semantic UI-CheatSheet | szhshp 的第三边境研究所 Typescript: Getting Started | szhshp 的第三边境研究所 Flutter-Getting Started | szhshp 的第三边境研究所 Typescript: Access window object with type check | szhshp 的第三边境研究所 VSC Extension Development-Create A Code Formatter Extension | szhshp 的第三边境研究所 OneNote Extension-Main API | szhshp 的第三边境研究所 TortoiseGit Win10 Icon not showing correctly | szhshp 的第三边境研究所 Mongoose: aggregate() 方法实现聚合函数 | szhshp 的第三边境研究所 React In Depth - React 源码解析 - render() & Fiber | szhshp 的第三边境研究所 MongoDB x Mongoose: 实现类似 Join 的功能 | szhshp 的第三边境研究所 Disqus 评论框改造工程-实现 Disqus 代理的 Serverless 服务 | szhshp 的第三边境研究所 GUI, CLI, Terminal, Shell, TTY, Console, Bash | szhshp 的第三边境研究所 Jest Async Best Practise: No Nested Async | szhshp 的第三边境研究所 关系型数据库与非关系型数据库优缺点分析 | szhshp 的第三边境研究所 New Edge & Chromium Error - Package is invalid: 'CRX_VERSION_NUMBER_INVALID' | szhshp 的第三边境研究所 选择 GraphQL 的 N 个理由 | szhshp 的第三边境研究所 StrokePlus - 鼠标手势神器的代码编写技巧 | szhshp 的第三边境研究所 嗨,好久不见 | szhshp 的第三边境研究所 Vue + ElementUI 集成 Vue Router | szhshp 的第三边境研究所 IE8 - Unknown Runtime Error Using innerHTML & Ajax | szhshp 的第三边境研究所 React: Handling Events | szhshp 的第三边境研究所 React-Navigation Integration with Redux | szhshp 的第三边境研究所 React: States is tricky | szhshp 的第三边境研究所 《10101》EP14:小剧场 | szhshp 的第三边境研究所 ColdFusion - Basic - arguments in cffunction | szhshp 的第三边境研究所 ColdFusion - Basic - cfset | szhshp 的第三边境研究所
Disqus RIP! 论过高的维护成本如何治疗固执的坏习惯 | szhshp 的第三边境研究所
2025-04-20 · via szhshp 的第三边境研究所

Meta

目录

直到今天当前站点还在使用 Disqus, 但很显然大多数人都不喜欢 Disqus.

IT’S A LONG STORY

  • 2015 年: 博客刚开始的时候用的评论插件是友言.
  • 2016 年: 短期切换到多说和来必力.
  • 2017 年: 最终完全迁移到了 Disqus, 为此我还写了一篇 迁移教程.

每一次迁移都是各种原因, 服务商的倒闭, 收费策略的变化, 以及对用户隐私的担忧.

2017-2018 年再度完善 Disqus 的时候, 还在想, 这下应该是长久之计了吧.

当初正好有时间折腾, 于是将 Disqus 的一系列缺陷用各种方法修补并稳定运转至今.

这一路的缝缝补补甚至让我写了不少东西

  • 众所周知, Disqus 是一个仅存在于 外星 的评论系统, 在地球加载需要一些法术
    • Patch 1 : 通过 AWS 进行反向代理以实现评论跳出大气层
    • Patch 2 : 检测网络的情况以加载两套不同的 Disqus 评论框, 完整功能的原生 Disqus 和简化版的定制 Disqus
    • Patch 3 : 换用 Now.js 的 Serverless 实现代理
    • Patch 4 : 换用 Cloudflare 的 Workers 实现代理
  • 再到后来, 我觉得我很不喜欢两套评论框, 于是自行封装了 Disqus 的 API
    • Patch 5 : 使用 NextJS 的 API Routes 进行封装和代理
  • 当初, 匿名评论存在问题, 当初几番周折发现官方有一个未在文档中提及的 Anonymous Key
    • Patch 6 : 使用 Anonymous Key 进行匿名评论
  • 其中还有一次发现自行封装的 Proxy CommentBox 存在 XSS 问题
    • Patch 6.1 : 官方文档从未提及 Comment 的 Type, 以至于我直接将 raw message 给渲染出来了
  • 评论框不支持 Markdown, 简直无法相信, 他们这么大体量的用户, 2024 年 5 月 Disqus 才开始支持 Markdown
    • Patch 7 : 使用 Markdown-it 实现评论的 Markdown 渲染
    • Patch 7.1 : 原生的 Disqus 并无法渲染 Markdown, 它还是使用富文本来表现 Markdown 的效果, 因此我对此做了区分展示
    • Patch 7.2 : Proxy CommentBox 没有表情选择器, 于是我自己集成了 Emoji Mart
  • 其间还有无数次 Post Router 修改导致评论 Identifier 的变化, 为此我也进行了无数次的 remap
    • Patch 8 : I HATE DISQUS MIGRATION TOOLS
  • 还有匿名评论者无法收到邮件通知这类问题, 甚至有朋友认为我一直都 已读未回
    • Patch 9 : 使用 AWS 自建 SMTP 服务器进行邮件通知, 每隔一段时间我的 AWS 就被大气层封锁, 于是我改了又改, 也是为此学习了 Docker 基础方便我迁移服务器
  • 2023 年 React18 带着 RSC 正式发布, 几乎同时后 NextJS 13 也一同更新, 从此可以抛弃反向代理服务器
    • Patch 10 : 2024 年, 我将整个站点依赖升级并将之前所有代理移动到 Server Action, 通过 Edge Function 访问我自行封装的服务, 因为 Vercel 天然在大气层外, 不需要做穿越的操作
  • 直到 2025 年, 我前两个月进行了最后一次修改
    • Patch 11 : 更新 Markdown Renderer 将 从原生 Disqus 里面添加的图片在 Proxy Disqus 里面展示出来

论过高的维护成本如何治疗固执这个坏习惯

在这一路的折腾中, 我也一直在想, 这 Disqus 真的还好用吗?

很明显在最近这些年有很多不错的评论插件逐渐成熟, 例如 Gitalk, Artalk, Waline 等等, 还可以用 Github Issues 来作为评论系统.

这时候我应该会在这里放出一份各个评论系统的调研和对比表:

评论系统优点缺点适用范围
Disqus成熟大平台, 生态完善, 多语言配置复杂, 大气层封锁, 维护困难, Markdown 支持差适合大部分博客, Client 静态引入, 稳定后台
其他

没错, 根本就没有什么个人调研结果

你也许觉得我在偷懒, 上面直接写成 其他 , 但是并非如此.

最近在阅读的书里面告诉我一些决策的原则:

What happens when there are no “best practices”? The nice thing about best practices is that they’re relatively risk-free ways to achieve certain goals. They’re called “best” (not “better” or “good”) for a reason—you know they work, so why not just use them? But one thing you’ll quickly learn about software architecture is that it has no best practices. You’ll have to analyze every situation carefully to make a decision, and you’ll need to communicate not just the “what” of the decision, but the “why.”

---- Chapter 3. The Two Laws of Software Architecture: Everything’s a Trade-Off, 《Head First Software Architecture》

你不应该仅参考我个人的调研结果, 也不应期望我的经验完全适用于你的架构不同的站点. 相反, 你应该根据自身需求借助 AI 分析需要做哪些 Trade-off.

我的需求:

  1. 能够无缝集成到 Next.js 和 React 的网站架构中
    1. (可选 1) 支持完全基于 Client 或 Serverless 的实现
    2. (可选 2) 支持通过 Server Action 或 Edge Function 的实现
  2. 支持 Markdown 渲染
  3. 配置过程简单直观
  4. 提供邮件通知功能
  5. 对 SEO 友好
  6. 尽量减小 Bundle Size
  7. 前端样式和功能可定制
  8. 维护成本低
  9. 迁移成本低

简单对话后我得到的结论是 Waline 或者 Twikoo

并且我需要做的 Trade-Off:

  1. 放弃 Disqus 的生态
  2. 花费额外 Effort 进行评论迁移
  3. 放弃至今所有 Custom Patch 的功能 (我早就觉得那是一堆屎山了维护成本太高了)
  4. 放弃完全定制前端的自由度, 换为单纯定制 Style (为了完全的自由度重新造轮子真的不明智)
  5. 放弃 Disqus 对于已注册用户的邮件通知, 自行接入邮件 Provider

我在原地思考三分钟后, 我认为可以尝试替代现有的 Disqus.

于是我用半小时快速做了一个 Waline POC 站点, 测试良好之后开始正式迁移.

很幸运, 我花费了两个晚上搞定了所有

非常讽刺的是, 光是 维护成本急剧降低 的这一点好处, 就足以让我在前几年直接放弃 Disqus. 但是我一直在嘴硬, 我一直在说 Disqus 是最好的评论系统 , Disqus 是成熟的评论系统 , Disqus 是最适合我的 .

上面所有 Custom Patch 在这一天被全部清除, 你都无法想象用 2 个文件替换掉其他十几个文件是多么的痛快:

对于数据库和邮件提醒我都使用了三方 Vendor, 我这个网站从来都没有服务器.

至今一切尘埃落定, 到下面评论框测试一下吧!

Disqus RIP!