<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>blog-dev on Reorx’s Forge</title><link>https://reorx.com/tags/blog-dev/</link><description>Recent content in blog-dev on Reorx’s Forge</description><image><url>https://reorx.com/images/forge-v2-compat.svg</url><link>https://reorx.com/images/forge-v2-compat.svg</link></image><generator>Hugo -- gohugo.io</generator><lastBuildDate>Mon, 12 Sep 2022 00:00:00 +0800</lastBuildDate><atom:link href="https://reorx.com/tags/blog-dev/feed.xml" rel="self" type="application/rss+xml"/><item><title>关于 Essays 的说明</title><link>https://reorx.com/essays/2022/09/about-essays/</link><pubDate>Mon, 12 Sep 2022 00:00:00 +0800</pubDate><guid>https://reorx.com/essays/2022/09/about-essays/</guid><description>Essays 板块已经正式加入我的个人网站——也就是你现在正在浏览的这个网站，正好用第二篇来说明下创建它的动机和它的设计。 开始写博客至今已有几个月了，但</description><content:encoded><![CDATA[<p>Essays 板块已经正式加入我的个人网站——也就是你现在正在浏览的这个网站，正好用第二篇来说明下创建它的动机和它的设计。</p>
<p>开始写博客至今已有几个月了，但我每次写文章时仍然会有这几个问题：</p>
<ol>
<li>动笔难。哪怕有了想法，甚至有了笔记，也总是会因为惧怕组织文章结构而难以下笔。</li>
<li>写字不够专注。一开始是经常被其他事情打断，久了竟然导致无法长时间专注写字，写一会就不由自主地去刷 Twitter / Telegram / RSS。</li>
<li>博客文章变得过「重」了，潜意识里觉得是一件需要很多时间来去做的事情，而且由于是静态生成器架构，必须要在有 Markdown 编辑器和 Git 全套工具的电脑上进行。</li>
</ol>
<p>我逐渐发现若只写长文，博客的更新频率必然不高，不利于持续输出，因此最好的办法就是为自己的写作设定一个新的分类，这就是 Essays 的由来。</p>
<p>Essays 专门用于发表片段化的想法，对文章结构和长度不做要求，并且我希望每篇都尽量在 20 分钟内写完，践行 Clear Communication。</p>
<p>有了 Essays，原来的文章则属于 Blog 板块。Blog 的定位是内容丰富的长文，Essays 则适合记录在产品和技术创作之外，我对这个世界的感受和思考。</p>
<p>我对网站结构也进行了一些改进，之后会出一篇专门的文章详细说明。这里着重说下 RSS 的变化，首页的 RSS 会包含全站所有文章，而 Essays / Blog 页面下的 RSS 则仅包含其所在板块的文章。如果读者有需求，可以考虑订阅不同的链接。</p>
<p>我还为 Essays 增加了一个 n8n workflow <sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>，自动将最新的文章分享到 Twitter。如果你现在是在 Twitter 的图片中阅读本文，那么这条推文以及图片都是由 n8n 生成并发送的。</p>
<p>我希望能越来越多地分享我的想法、知识、体验，Essays 就是这样一个尝试。下一个目标，是能够随时随地写作并分享，我已经有了一个<a href="https://t.me/reorx_share/2221">初步的想法</a>，看看我能创造些什么吧。</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>参见我的另一篇文章 <a href="https://reorx.com/blog/sharing-my-footprints-automation/">使用自动化工作流聚合信息摄入和输出</a>&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded></item><item><title>更换博客评论系统</title><link>https://reorx.com/blog/blog-commenting-systems/</link><pubDate>Sun, 29 May 2022 00:00:00 +0800</pubDate><guid>https://reorx.com/blog/blog-commenting-systems/</guid><description>整理了一份比较完整的评论系统评测列表，并详细介绍了最终选择的 Remark42。</description><content:encoded><![CDATA[<h2 id="告别-disqus">告别 Disqus</h2>
<p>博客建成也有一段时日了，渐渐也会收到一些读者的评论，在和大家交流中学到了很多新的知识，我很喜欢这种感觉，把评论看做我和读者之间重要的交流渠道。有一天我收到了 <a href="https://twitter.com/geekdada">@geekdada</a> 在 <a href="/blog/deploy-umami-for-personal-website/">搭建 umami …</a> 下的留言:</p>
<blockquote>
<p>非常感谢推荐。不知道作者有没有想把 Disqus 换掉，又臃肿又收集数据。</p>
</blockquote>
<p>于是我开始留意起 Disqus 的使用体验。其实我在 2013 年就注册了 Disqus，用在了自己最早的一版个人网站上，对它也算是有些感情，这也是一开始快速实现时选择它的原因。</p>
<p>我打开 Chrome Dev Tools，刷新文章页，果然看见一大堆请求，一共有 94 次，这可太恶心了！且不论它收集了哪些统计数据和用户隐私，光是数量之多就让有代码洁癖的我无法忍受。</p>
<p><img loading="lazy" src="/blog/blog-commenting-systems/images/disqus.png" type="" alt=""  /></p>
<p>再试探性地关掉 ublock，这下更不得了，显示出有半个屏幕之大的广告区域，充斥着猎奇的图片和 clickbait 标题的链接。去设置页看了下，果然只有付费用户才可以关闭广告，但接连被恶心到，我已经彻底决定抛弃 Disqus。</p>
<p>就像之前从 Google analytics 换到 umami 那样，我踏上了寻找新的评论系统的旅程。</p>
<h2 id="评论系统的选择">评论系统的选择</h2>
<p>经过一番调查，我大致将评论系统分为了如下几类，每类都放上我认为最好的几种可选项，为同样带着自己的需求寻找评论系统的读者提供参考。</p>
<ul>
<li>
<p><strong>Full-fledged</strong></p>
<p>全功能的评论系统，从前端的 UI 组件到后端的 API、数据存储都完整实现。其下又分为 SaaS 和 Self-hosted 两类。</p>
<ul>
<li>
<p><strong>SaaS</strong></p>
<p>Disqus 就是属于这一类产品，优点是配置便捷，不用操心；缺点则是可能会收集隐私数据，缺乏可控性，并且价格都比较贵。</p>
<ul>
<li><a href="https://commento.io/">Commento</a>: 目前是我最喜欢的一个 SaaS 评论系统，界面简洁清爽，能适应大部分博客的主题样式，无广告和追踪。价格为每月 $10。</li>
<li><a href="https://commentbox.io/">CommentBox</a>: 我很早收藏过的一个评论系统，和 Commento 一样的 slogan 和价格，就是功能和设计看起来要弱一些。</li>
</ul>
</li>
<li>
<p><strong>Self-hosted</strong></p>
<p>与一般的互联网服务不同，评论系统中 Self-hosted 的比例反而比 SaaS 化的大很多，这大概是因为自建博客的市场比较小众，且使用者也多为喜欢造轮子的程序员。Self-hosted 虽然较为麻烦，但优势也非常明显——由开源带来的高可控性、高定制性，并且近年来 PaaS 平台的蓬勃发展大大降低了部署成本，不需要拥有服务器便可一条龙 0 元购搭建起来。因此如果你有一定的技术基础，非常建议尝试自部署一套评论系统。</p>
<ul>
<li><a href="https://github.com/umputun/remark42">Remark42</a>: 我最喜欢的一个 self-hosted 评论系统，也是本文接下来所要讲解的对象。</li>
<li><a href="https://github.com/posativ/isso">Isso</a>: 使用 Python 开发，数据库为 SQLite。界面复古而简洁，适合 minimalist。Isso 可以配置评论自动通过，或者先审核再通过。</li>
<li><a href="https://github.com/djyde/cusdis">Cusdis</a>: 我很佩服的开发者 <a href="https://lutaonan.com/">Randy</a> 的作品，也是使用 SQLite 作为数据库，就像是 Isso 的 Nodejs 翻版，但界面更加美观。与 Isso 不同的是，Cusdis 要求评论必须通过人工审核才可以显示，提供了 Email 和 Dashboard 两种审核方式。</li>
<li><a href="https://github.com/adtac/commento">Commento</a>: SaaS Commento 的开源版，使用 Go 开发，支持各种 social auth 登录，甚至可以配置 SSO。但这个项目已经停止更新一年多了，如果你有兴趣，可以考虑使用社区 fork 维护的 <a href="https://github.com/souramoo/commentoplusplus">Commento++</a>，作者的更新还挺活跃的。</li>
<li><a href="https://twikoo.js.org/">Twikoo</a>, <a href="https://artalk.js.org/">Artalk</a>, <a href="https://valine.js.org/">Valine</a>: 三者都是面向国内用户所开发的评论系统，有很多相似之处，因此放在一起介绍。与上述其他项目不同的是，三者的接入方式并非 iframe，而是直接操作网页的 DOM 元素。
<ul>
<li>Twikoo 主要支持腾讯云 CloudBase，也可以部署到 Vercel。数据库是 MongoDB。更新<a href="https://github.com/imaegoo/twikoo/graphs/contributors">比较活跃</a>。</li>
<li>Artalk 使用 Go 开发，无部署环境限制，支持常见的 RDBMS。更新<a href="https://github.com/ArtalkJS/Artalk/graphs/contributors">近期较为活跃</a>。
<mark>Artalk 的作者 <a href="https://qwqaq.com/about/">qwqcode</a> 去年高考步入大学，开发 Artalk 的时候刚上高一。在三年里独立完成 Artalk 从 PHP 向 Go 的架构转变，TypeScript 也写的贼溜，<a href="https://twitter.com/novoreorx/status/1532175668766683136">现在的年轻人真是越来越强了</a></mark>。</li>
<li>Valine 似乎只支持 LeanCloud 部署，已经<a href="https://github.com/xCss/Valine/graphs/contributors">很久没有更新</a>了。</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>
<p><strong>Proxied</strong></p>
<p>类似 full-fledged，有自己实现的 UI 和 API，但数据存储依托于一个已有的其他服务。我个人并不偏爱此类应用，一者登录方式被限制在其所依托的服务上，再者数据也不好维护。</p>
<ul>
<li><a href="https://github.com/utterance/utterances">utterances</a>: 应该是最早的基于 GitHub 的评论系统，提供了一个用于接入评论的公开服务。</li>
<li><a href="https://github.com/giscus/giscus">giscus</a>: utterances 的 fork 版，增加了自部署的能力。</li>
</ul>
</li>
<li>
<p><strong>IM Plugin</strong></p>
<p>由即时通讯服务提供的插件。这是个顺理成章的思路，对于即时通许服务商来说，可以利用已有的基础设施提供更多的 user engagement，何乐而不为呢。其中最为知名的当属 Facebook，Google 曾经也有，但和 Google Plus 一同被埋葬了。这种评论系统也存在登录方式单一的问题，请谨慎选择。</p>
<ul>
<li><a href="https://comments.app/">Comments.app</a>: Telegram 提供的网站评论插件，使用简便，界面美观，支持 dark mode 和 accent color。</li>
<li><a href="https://core.telegram.org/widgets/discussion">Discussion Widget</a>: 同样是 Telegram 的服务，但与 Comments.app 的不同在于，Discussion Widget 原本的设计目的是将 Channel 消息中的评论嵌入到网页中，但我发现这同样是一种评论系统，并且多出了将评论对应到 Channel 消息的功能。我在探索中已经顺便将 Discussion Widget 实现到了博客主题中，你可以在这个页面中预览和尝试: <a href="/playground/comment-telegram/">Commenting System: Telegram Widget</a></li>
<li><a href="https://developers.facebook.com/docs/plugins/comments/?locale=en_US">Meta Comments Plugin</a>: Meta (Facebook) 的评论插件，我的社交圈里基本没人使用 Facebook，因此不予评价。</li>
</ul>
</li>
<li>
<p><strong>Static</strong></p>
<p>静态评论，即评论作为静态网站原始数据的一部分，跟随网站的构建流程生成到页面中。不同于其他评论系统可以灵活嵌入到任何页面，静态评论只能用于静态网站中。评论的数据是否应该属于网站本身呢？这是一个非常两极分化的问题。</p>
<ul>
<li><a href="https://welcomments.io/">Welcomments</a>: 静态评论 SaaS 服务，需要用户绑定自己网站的 GitHub 仓库。当有人评论时，Welcomments 会生成一个 commit 包含评论的数据提交到仓库中，触发 GitHub 的自动构建流程，将评论更新到静态网页中。Welcomments 支持在它的网站上进行评论审核，还接入了 <a href="https://akismet.com/">Akismet</a> anti-spam 服务，每月 $6，年付减为 $4。</li>
<li><a href="https://github.com/eduardoboucas/staticman">Staticman</a>: 更为强大的 Welcomments，并且是 self-hosted。Staticman 支持更多的代码托管平台，并且可以通过 pull-request 的方式审核评论，这才是基于 Git 的工作流应有的样子。但 Staticman 已经有 2 年没更新了，在进行更深入的调研之前，不建议作为第一选择。</li>
<li>手动维护: 任何手动维护评论的方式。有的博主会在网站会留下邮箱、即时通讯号等联系方式，让读者将想要评论的内容发送过去，然后将评论内容手动更新到文章的评论区。这种方式虽然简陋，但也不失为一种最简单的实现手段，毕竟评论的本质就是交流。</li>
</ul>
</li>
</ul>
<h2 id="我的选择-remark42">我的选择: Remark42</h2>
<p>基于如下这些原因，我在众多评论系统中选择了 Remark42。</p>
<h3 id="技术层面">技术层面</h3>
<ul>
<li>它使用 Go 语言实现，我很难抗拒二进制单文件的诱惑。</li>
<li>它使用基于文件的数据库。我最喜欢的数据库是 SQLite，单文件无任何依赖，Remark42 使用的 <a href="https://github.com/etcd-io/bbolt">boltdb</a> 也是基于文件，对我来说和 SQLite 一样美好。</li>
<li>它有较为现代化的前端技术栈，使用 TypeScript, Preact, Postcss 开发。</li>
<li>它是一个成熟的开源项目，文档全面、开发时间长，基本上我的任何问题都可以在文档和 Issues 中找到解答。</li>
<li>它的 <a href="https://remark42.com/docs/contributing/api/">API</a> 非常完善，比如导入导出都可以用一行 curl 来完成。在其他方面作者也显示出很高的<a href="https://remark42.com/docs/contributing/technical-details/">技术品味</a>。</li>
</ul>
<h3 id="视觉层面">视觉层面</h3>
<p>Remark42 界面简洁美观，虽然比 Isso 和 Cusdis 复杂，但依然保持了足够的适应性和可塑性。</p>
<figure class="center align-center">
  <img loading="lazy" src="/blog/blog-commenting-systems/images/remark42-1.png" type="" alt=""  />

  <figcaption><p>Remark42 简洁的界面</p></figcaption>
</figure>

<h3 id="功能层面">功能层面</h3>
<p>我其实不喜欢 pre-moderation，即评论必须先通过审核才可以显示，这会给我带来额外的工作量，并且评论者也没法得到即时的效果反馈。但我也不想开放无审核的匿名评论，给自己带来被评论机器人攻击的风险。</p>
<p>我想到的折中方案是，首先提供尽可能多的 social auth 登录方式，比如 Twitter, Google, GitHub，这些 Remark42 都支持；再提供一种基于邮箱的认证方式，这是 Remark42 最大的亮点——Passwordless Authentication。评论者输入邮箱，点击 login，Remark42 会向其发送一个含有 token 的邮件，评论者使用这个 token 完成登入便可以进行评论。</p>
<p>邮箱认证是我个人最喜欢的登录方式，因为社交账号登录总是会存在风险，服务会拿到可以访问用户数据的 access token，你不知道它会做些什么 <sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>。而邮箱不存在用户数据，唯一的担忧是被 spam 骚扰，但有很多匿名邮箱和邮件转发服务帮助我们解决这个问题。<del>使用邮箱登录进行的评论，在被回复后也会发送邮件提醒评论者，确保了双向沟通的流畅性</del><sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup>。</p>
<p><figure>
      <video class="video-shortcode" preload="metadata" controls>
        <source src="/blog/blog-commenting-systems/images/remark42-email-login.mov">
        There should have been a video here but your browser does not seem to support it.
      </video>
      </figure></p>
<p>Remark42 还有一个特别的地方，它没有 Admin 界面，或者 Dashboard，这得益于其清晰的设计理念和完善的功能实现。一般对于评论系统来说，Admin 主要用于查看和审核评论，但 Remark42 不需要审核，而对评论和评论者的操作（隐藏、删除、屏蔽）都集成在评论控件中。加上 API 简单易用，去掉 Admin 不仅没有让人感到不便，反而成为一个值得一提的 feature 了。</p>
<p>最后，Remark42 在设计上就支持 multi-site，只需要部署一个实例，便可以为多个不同域名的站点提供评论服务。</p>
<h3 id="隐私层面">隐私层面</h3>
<p>Remark42 的标语是「Privacy-focused lightweight commenting engine」，而它的确在隐私这件事情上做了许多事情。无追踪和广告自不必说，尽可能少的申请 OAuth 权限也只是基操，Remark42 还对用户数据做了这些考虑：</p>
<blockquote>
<p>Users can request all information Remark42 knows about them and receive the export in the gz file.</p>
</blockquote>
<p>用户可将自己在一个 Remark42 服务中的所有评论数据导出，多希望我高中时使用的百度空间也有这个功能。</p>
<blockquote>
<p>Supports complete cleanup of all information related to user&rsquo;s activity by user&rsquo;s &ldquo;deleteme&rdquo; request.</p>
</blockquote>
<p>用户可以通过 &ldquo;deleteme&rdquo; 请求将所有与自己相关的数据全部清除，类似近年来用户呼吁各大网站去支持的 opt-out <sup id="fnref:3"><a href="#fn:3" class="footnote-ref" role="doc-noteref">3</a></sup>。</p>
<h2 id="小结">小结</h2>
<p>Remark42 还有许多功能，比如评论的 RSS 输出、Telegram 通知接入、Webhook 等等，限于本文篇幅，就不做展开了。下一篇博客我会对如何在 <a href="https://fly.io/">Fly.io</a> 部署 Remark42、自定义 UI、接入 CDN 等内容进行详细的讲解，让读者也可以快速搭建自己的 Remark42 实例，敬请期待。</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>虽然一个优秀的服务应尽可能少的申请用户权限（减少 scope），但遇到糟糕的服务申请过多权限，我们一个不留神点了 Allow 的风险依然存在。&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:2">
<p>经过尝试和搜索，发现 Remark42 的用户提醒是一项单独的功能（Subscribe），与是否用邮箱登录无关。我打算为邮箱登录实现一个「subscribe to notification」的勾选框，实现登录后即可自动订阅邮件提醒，见此 issue 下的<a href="https://github.com/umputun/remark42/issues/745#issuecomment-1144526472">评论</a>。&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:3">
<p><a href="https://justdeleteme.xyz/">JustDeleteMe</a> 列出了各大网站对删除账户数据的支持情况，并提供直达链接。&#160;<a href="#fnref:3" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded></item></channel></rss>