Detalk.js —— 具有高自定义性、简洁、轻量的开源评论系统

2023-01-11 14:23:58 浏览数 (1)

为什么开发 Detalk.js?

我一直在寻找开源、可以免费部署的评论系统,在 Valine 发现隐私问题和 XSS 漏洞后,我就放弃了 Valine 和「无后端」解决方案。

Waline 是「有后端的 Valine」,保留了 Valine 的很多特性,但还是没有让我满意。

后来,我转到了 Twikoo,这也是我使用最久的评论系统。它有非常丰富的特性,但我最后还是弃用了它。

Detalk.js 的部署平台从名字就可以看出,基于 Deta Bases 和 Deta Micros. 这些平台对个人开发者免费使用,非常的友好。

服务端开发

Detalk.js 一开始就选择优先开发服务端,而前端则可以随意构建,有完整的服务端文档。

所以,我将主代码放到了 detalkjs/server 中,得益于 Deta 平台,现在可以一键部署,稍等片刻就可以直接使用。

服务端我直接从官方的 Demo 开始写,使用官方推荐的 Express 框架,代码语言选择 JavaScript.

在开发过程中,我发现 Detalk.js 的响应时长至少在 1s ,我推测是与 Deta 平台的运行方案和冷启动有关,但对于评论系统来说,这无伤大雅。

数据库

Deta 平台上,最方便的数据库就是 Deta Bases. 这又是一款 Key-Value 数据库,有着简单易于理解的 SDK 文档。

导入方法也很简单:

代码语言:javascript复制
const { Deta } = require('deta');
const deta = Deta();
// 为了方便用户部署多个 Detalk,用户可自定义 Base Name.
const db = deta.Base(process.env.BASE_NAME || 'detalk');

使用方法整体类似于 yfun-lab/gh-worker-kv,对于部分代码的上手也是很简单的。

前往 Web 面板截图,可以看到,Detalk 所创建的数据库基本格式如下:

CMT_ 开头的存放评论,FUNCTION_ 开头的存放事件函数,还有一些关于站点的配置。

API

目前,所有后端的 API 都在 API | Detalk.js 可以查看。

部分 API 需要鉴权登录操作,部分为公共 API,只需要后端地址即可调用。

前端开发

我对前端 detalkjs/client 的简介是:

⚡ The fastest way to add Detalk (Based on Deta) to your website. | 将 Detalk (Based on Deta) 加入你的网站。

(这再次说明官方提供的前端只是一种方案,完全可以自己开发

也正因如此,前端的 NPM 包名是 @detalk/static (逃

打包

前端打包是 Webpack 5 方案,我多加了一个配置文件,可以打包出 JS, CSS 分离的版本。这样或许可以方便部分用户的引入需要。

但是从各方面来看,还是建议引入单 JS 的版本,大小约为 43kb,Gzip 压缩后约 12kb.

前端配置?

设计前端时有两种读取配置文件的方案,一种是类似于 Twikoo,从服务端读取,另一种是直接在 detalk.init 时配置。

明显,前者需要多发送 1 - 2 次 HTTP 请求,加载速度也会变慢,所以我选择了后者。

控制面板

控制面板也可以使用完全 API 自构建,但是,我们提供了「依托答辩」的官方后端:https://detalk-dash.netlify.app/

除可维护角度以外,都挺好的(

一些问题

Markdown 解析

如果你没有额外的配置,那么点击「预览」的时候。你肯定会发现需要等待一段时间。

我之前想把 Marked.js(号称轻量)的 Markdown 解析器加入 Detalk.js,结果发现包体积直接翻了一倍,于是放弃。

如果你需要更换解析器,不用担心,这里给出了方法。

URL 载入配置

前文说到,Detalk 并没有采取后端配置的方法,但是,我们还是支持了从 URL 载入配置。

关于这一特性,可见此处。

多语言的实现

Detalk.js 并没有默认提供多语言功能,这主要是因为不同站点的使用者受众不同,于是我决定这项功能可以由用户实现。

这依赖 window.DETALK_I18N 参数,如果没有此项,则会在 detalk.init 时由程序默认提供简体中文项。

实现代码可以见如下:

代码语言:javascript复制
if (navigator.language == 'zh-CN') {
  window.DETALK_I18N = {
      loadMore: '加载更多',
      notAllowedInput: '输入内容不符合要求!',
      send: '发送',
      preview: '预览',
      reply: '回复',
      replyTo: '回复',
      cancel: '取消',
      loadingLoginFrame: '登录窗口加载中...',
      gotoLoginFrame: '请在登录窗口中继续',
      waitingInfo: '登录成功,正在获取用户信息...',
      loginSuccess: '登录成功',
      failedLoadingInfo: '获取用户信息失败',
      deleteConfirm: '即将删除 ID:[#ID] 评论,是否继续?',
      total: '共 [#TOTAL] 条评论',
      noComment: '暂无评论',
      up: '正序',
      down: '倒序',
      delete: '删除',
      top: '置顶',
      login: '登录',
      required: '必填',
      optional: '选填',
      nickname: '昵称',
      email: '邮箱',
      link: '网址',
      day: {
      justNow: '刚刚',
      minute: '[#TIME] 分钟前',
      hour: '[#TIME] 小时前',
      day: '[#TIME] 天前',
  }
} else if (navigator.language == 'zh-TW') {
    window.DETALK_I18N = {
      loadMore: '加載更多',
      notAllowedInput: '輸入內容不符合要求!',
      send: '發送',
      preview: '預覽',
      reply: '回复',
      replyTo: '回复',
      cancel: '取消',
      loadingLoginFrame: '登錄窗口加載中...',
      gotoLoginFrame: '請在登錄窗口中繼續',
      waitingInfo: '登錄成功,正在獲取用戶信息...',
      loginSuccess: '登錄成功',
      failedLoadingInfo: '獲取用戶信息失敗',
      deleteConfirm: '即將刪除 ID:[#ID] 評論,是否繼續?',
      total: '共 [#TOTAL] 條評論',
      noComment: '暫無評論',
      up: '正序',
      down: '倒序',
      delete: '刪除',
      top: '置頂',
      login: '登錄',
      required: '必填',
      optional: '選填',
      nickname: '暱稱',
      email: '郵箱',
      link: '網址',
      day: {
      justNow: '剛剛',
      minute: '[#TIME] 分鐘前',
      hour: '[#TIME] 小時前',
      day: '[#TIME] 天前',
  }
}

最后

Detalk.js 未来会与 ESHexoN 融合,在 ESHexoN 中提供管理面板。

同时,YFun's Blog 也会在后续更新有关 Detalk.js 的更多文章。

目前,此博客已经更换至 Detalk.js 评论系统,欢迎测试与使用!

0 人点赞