Hexo使用Waline评论系统

最近折腾博客比较多,也看了不少使用Hexo博主所用的评论系统,觉得Valine不错,NexT也天然支持(配置也就简单)。正想切换时发现它存在安全性问题,于是就调研了一下可用的评论系统,简单总结:

  • Disqus: 好用好配置,但国内访问不了(弃用原因)
  • Valine: 好用好配置,但存在 # 安全性问题
  • Github issue: 应该可用,没有亲自尝试
  • Remark42: 自行部署,但对于https网站需要一个可用域名

我对评论系统的需求:

  • 用户评论方便:支持匿名评论,不强制登录,降低用户评论门槛
  • 数据可迁移:将来如果切换到其他评论系统比较方便
  • 不要求独立域名
  • 无安全问题

这几条限制加上之后,可选项也就不多了,最终选择了Waline。本文所用版本:Hexo v5.4.0,NexT v8.5.0。

配置Waline

上文提到了Valine有 # 安全性问题,简单说就是serverless架构导致前端直接访问存储,从而存在数据暴露风险。而Waline解决问题的方法是加了一层,使用Vercel部署了一个 webapp 从而隔离了前端和存储,避免了安全问题。但部署也略复杂一些,server和client都要部署。

服务端的配置不再多说,按照 # 官方文档 步骤一步步来即可。如果没用过Vercel的话,在这一步可能会有一点卡壳。不过也是通过这次配置发现了这么个有趣的免费serve webapp的网站 :-),这暂不展开。

客户端的配置说起来简单,就是需要把一段js嵌入到需要评论的页面中去。第一反应是看Hexo的NexT主题是否天然支持Waline,答案是否定的。搜了一下发现Waline的作者给NexT提过PR,但并未被采纳:

https://github.com/next-theme/hexo-theme-next/pull/147

Thanks for your contribution. Unfortunately, we cannot accept any comment systems related to Leancloud or Valine until we have thoroughly investigated the attack against Valine that occurred a few days ago. Ensuring user data security and privacy protection is our consistent pursuit, and we are planning to remove Valine in the next version. Maybe you can make your comment system into a third-party plug-in like this: https://github.com/next-theme/hexo-next-valine And submit a pull request here: https://github.com/next-theme/awesome-next#comment

好了,那就用第三方的插件, @waline/hexo-next 。结果使用npm install在Hexo目录安装后发现并不生效,运行hexo s出现如下错误:

$ hexo s
INFO  Validating config
INFO  Start processing
INFO  Hexo is running at http://localhost:5000 . Press Ctrl+C to stop.
Unhandled rejection Template render error: (/home/finisky/themes/next/layout/post.swig)
  Template render error: (/home/finisky/themes/next/layout/post.swig) [Line 41, Column 16]
  Template render error: (/home/finisky/themes/next/layout/post.swig) [Line 54, Column 17]
  Template render error: (/home/finisky/themes/next/layout/post.swig)
  Template render error: (/home/finisky/themes/next/layout/_partials/head/head-unique.swig) [Line 10, Column 23]
  Template render error: (/home/finisky/themes/next/layout/post.swig) [Line 3, Column 3]
  Template render error: (/home/finisky/themes/next/layout/post.swig)
  Template render error: (/home/finisky/themes/next/layout/_partials/header/index.swig) [Line 6, Column 15]
  Template render error: (/home/finisky/themes/next/layout/post.swig)
  Template render error: (/home/finisky/themes/next/layout/_partials/header/sub-menu.swig) [Line 2, Column 29]
  Template render error: (/home/finisky/themes/next/layout/post.swig)
  Template render error: (/home/finisky/themes/next/layout/_partials/header/sub-menu.swig)
  Template render error: (/home/finisky/themes/next/layout/post.swig) [Line 5, Column 3]
  Template render error: (/home/finisky/themes/next/layout/post.swig) [Line 9, Column 12]
  Template render error: (/home/finisky/themes/next/layout/post.swig)
  Template render error: (/home/finisky/themes/next/layout/_partials/comments.swig) [Line 3, Column 14]
  Template render error: (/home/finisky/themes/next/layout/post.swig)
  Template render error: (/home/finisky/themes/next/layout/_partials/languages.swig)
  Template render error: (/home/finisky/themes/next/layout/post.swig)
  Template render error: (/home/finisky/themes/next/layout/_third-party/math/index.swig) [Line 4, Column 16]
  Template render error: (/home/finisky/themes/next/layout/post.swig)
  Template render error: (/home/finisky/themes/next/layout/_third-party/quicklink.swig)
  Template render error: (/home/finisky/themes/next/layout/inject/bodyEnd/waline.swig) [Line 5, Column 15]
  Error: Unable to call `next_data`, which is undefined or falsey
    at Object._prettifyError (/home/finisky/node_modules/nunjucks/src/lib.js:36:11)
    at /home/finisky/node_modules/nunjucks/src/environment.js:563:19
    at Template.root [as rootRenderFunc] (eval at _compile (/home/finisky/node_modules/nunjucks/src/environment.js:633:18), <anonymous>:45:3)
    at Template.render (/home/finisky/node_modules/nunjucks/src/environment.js:552:10)
    at /home/finisky/themes/next/scripts/renderer.js:32:29
    at _View._compiled (/home/finisky/node_modules/hexo/lib/theme/view.js:136:50)
    at _View.render (/home/finisky/node_modules/hexo/lib/theme/view.js:39:17)
    at /home/finisky/node_modules/hexo/lib/hexo/index.js:64:21
    at tryCatcher (/home/finisky/node_modules/bluebird/js/release/util.js:16:23)
    at /home/finisky/node_modules/bluebird/js/release/method.js:15:34
    at RouteStream._read (/home/finisky/node_modules/hexo/lib/hexo/router.js:47:5)
    at RouteStream.Readable.read (node:internal/streams/readable:483:10)
    at resume_ (node:internal/streams/readable:981:12)
    at processTicksAndRejections (node:internal/process/task_queues:83:21)

看起来是找不到swig模板文件,感觉有点莫名其妙。后来想自己用Hexo扩展写个 script注入这些代码,但发现如果不改模板文件还不太容易实现。

更新NexT到v8.5.0

最后找到了问题的根源,我用的是 NexT v7.8.0。git log看了下最新的代码已经是去年的了。再搜索发现了个更匪夷所思的事情,我发现了两个repo: https://github.com/theme-next/hexo-theme-next 和 https://github.com/next-theme/hexo-theme-next

而且前者在Google中的排名更高,Star更多。但再一看二者的最新版本,下面的居然是 v8.5.0。研究了半天终于在这找到了区别:

https://github.com/next-theme/hexo-theme-next/issues/36

https://github.com/next-theme/hexo-theme-next/issues/4#issuecomment-626205848

  1. 简单来说,问题就是 theme-next 团队的 owner 始终拒绝向其它任何团队成员提供足够的权限,且 owner 本人自 2019 年 10 月起已连续半年不在线,导致其它活跃的团队成员无法管理仓库,也无法邀请新的成员。
    由于对 theme-next 团队的未来不抱有期望,我作为 theme-next 的主要贡献者,自 2020 年 4 月起停止为旧的仓库贡献代码,并创建了新的组织,以确保维护工作正常进行。

  2. 只要能够收到足够多的 Bugfix / Feature Request,每月更新肯定不是问题。

  3. 目前已经发布的版本在这里: https://github.com/next-theme/hexo-theme-next/releases
    v8.0.0 版本计划在 Hexo 5.0 版本后发布。

好了,问题变成了要把v7.8.0的NexT更新到v8.5.0,但由于两个repo是独立的,只能手动更新_config.yml。而且更大的麻烦在于如果之前直接修改过模板源码,升级版本就更是费劲。

按照官方推荐的方式更新到v8.5.0: https://theme-next.js.org/docs/getting-started/upgrade.html

然后一切就简单了,再在Hexo目录安装@waline/hexo-nexthexo clean & hexo g一次通过,效果直接看评论区。