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