1. 1. 为什么开发 Detalk.js?
  2. 2. 服务端开发
    1. 2.1. 数据库
    2. 2.2. API
  3. 3. 前端开发
    1. 3.1. 打包
    2. 3.2. 前端配置?
  4. 4. 控制面板
  5. 5. 一些问题
    1. 5.1. Markdown 解析
    2. 5.2. URL 载入配置
    3. 5.3. 多语言的实现
  6. 6. 最后

为什么开发 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 文档。

导入方法也很简单:

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 时由程序默认提供简体中文项。

实现代码可以见如下:

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 评论系统,欢迎测试与使用!