WARNING本文已归档,后续大概率不会更新,内容仅供参考。
前言
静态博客虽然有着安全、成本低、速度快等优点,但是内容管理和评论系统一直是一个难题。静态博客常见的评论解决方案有 Disqus、Giscus、Valine、Waline、Twikoo 等。
-
Disqus 虽然功能全面、方便使用,但是太臃肿了,加载速度慢、且对中国大陆网络不友好。
-
Giscus 是一个很好的方案,基于 GitHub 的 Discussions 功能,但是需要 GitHub 登录才能评论,对路人不友好。
-
Valine 虽然轻量化,但是
v1.4.0之后就闭源了,而且依赖于 Lean Cloud 免费版,数据安全性和可靠性有待考量。(而且国内版 Lean Cloud 还有查水表风险) -
Waline 相当于有后端的 Valine,但是完全开源,支持更多的数据库,解决了 Valine 的一些问题。
-
Twikoo 跟 Waline 类似,但是通知方式没有 Waline 多,文档也不够详细,是一个很有前景的方案。支持从 Waline 导入评论,也许某天它更成熟以后,我会迁移过去。
在经过仔细比较之后,我还是选择了Waline作为博客的评论方案,然而 Fuwari 本身并没有(积极地)支持评论功能,所以需要费点功夫。本文记录一下我为 Fuwari 接入 Waline 的过程,希望能帮助有同样需求的人。后续如果 Fuwari 官方支持了 Waline,本文也会持续更新。
NOTE本文并非面向小白,需要一定的编程基础。
成果展示
下图展示了接入 Waline 评论系统的结果。

准备工作
该部分并非主要内容,故仅简单说明一下。
先根据 Waline 官方文档部署 Waline 数据库以及后端服务,数据库我选择的是 MongoDB Atlas 提供的免费 512M 的 MongoDB 数据库;后端我选择的是 Vercel。
Waline 文档中对 MongoDB Atlas 的描述不够详细,可以参考 MongoDB Atlas | Twikoo 文档。数据库部署好之后在 Vercel 中配置环境变量即可,这一步需要参考 多数据库服务支持 | Waline 中的环境变量配置(我踩坑了,死活连不上数据库)。为了安全考虑,环境变量建议设置为Sensitive。
TIPMongoDB 和 Vercel 均可以选择区域,建议选择距离目标用户群体比较近的区域,并且 MongoDB 和 Vercel 最好选在同一区域。
接入 Waline
Fuwari 官方有一个很久没更新的 comments 分支(希望 Fuwari 今后能推进评论系统的集成),虽然该分支并没有支持 Waline,但是为我们提供了代码模板和思路。
我们需要先下载 comments 分支(不下载也行,缺少的文件/文件夹自己创建就好了),将其 src/components/comment 文件夹复制到自己博客的 src/components 目录下。模板里带有 Disqus.astro、Giscus.astro 和 Twikoo.astro 三个文件,如果不需要,建议删除。
接着在 src/components/comment 下新建文件 Waline.astro ,文件内容如下,这一步是添加 Waline 评论组件,相关的代码可参考 Waline 文档。
---import { commentConfig } from '@/config'
interface Props { path: string}
const config = { ...commentConfig.waline, el: '#waline', path: Astro.props.path, dark: 'html.dark', wordLimit: ["2", "300"],}---<!-- Waline --><div class="relative w-full"> <div id="waline"></div> <link rel="stylesheet" href="https://unpkg.com/@waline/client@v3/dist/waline.css" /> <script type="module" is:inline define:vars={{ config }}> import { init } from 'https://unpkg.com/@waline/client@v3/dist/waline.js'; init(config); </script></div>添加了 Waline.astro 之后,打开同目录下的 index.astro,将文件修改为以下内容,这一步是添加 comments 组件,并支持 Waline 服务。
---import type { CollectionEntry } from 'astro:content'import { commentConfig } from '@/config'import Waline from './Waline.astro'interface Props { post: CollectionEntry<'posts'>}
const { id, data, slug } = Astro.props.post
const path = `/posts/${slug}`const url = `${Astro.site?.href}${path}`const comments = data.comments
let commentService = ''if (commentConfig?.waline) { commentService = 'waline'}---{ comments == true && ( <div class="card-base p-6 mb-5"> {commentService === 'waline' && <Waline path={path} />} {commentService === '' && null} </div> )}接着需要修改 src/types/config.ts 中的 config 类型约束,我只添加了 serverURL 和 login 配置,需要更多配置可以参考 Waline 文档。
export type BlogPostData = { body: string; ... comments?: boolean; ... nextSlug?: string;};
export type CommentConfig = { waline?: WalineConfig}
type WalineConfig = { serverURL: string login?: string}接着需要修改 src/config.ts,首先需要引入 CommentConfig 类型定义,然后根据你部署到的 Waline,添加 Waline 配置。
import type { NavBarConfig, ProfileConfig, SiteConfig, CommentConfig, } from "./types/config";...export const commentConfig: CommentConfig = { waline: { serverURL: 'https://your-waline.com', login: 'enable' }};由于在 Comment 组件中有一个 comments == true 判断,用于对特定的文章启用或关闭评论,所以还需要修改一些文件。需要在 src/content/config.ts 添加如下的一行代码,默认开启文章评论功能。
draft: z.boolean().optional().default(false),comments: z.boolean().optional().default(true),description: z.string().optional().default(""),然后,需要修改 scripts/new-post.js 文件,在新建文章时添加 comments 选项。
draft: falsecomments: truelang: ''最后,修改文章的布局文件 src/pages/posts/[...slug].astro,导入并在合适的位置插入 Comment 组件即可。我选择在最后插入评论,你也可以根据自己的喜好插入。
import { formatDateToYYYYMMDD } from "../../utils/date-utils";import Comment from "@components/comment/index.astro";... <Comment post={entry}></Comment>
</MainGridLayout>后续工作
本文只是实现了最基本的 Waline 接入的工作,还有以下几个可以改进的方面:
-
Fuwari 的 comments 分支已经初具雏形,但是没有支持 Waline 评论系统,后续有时间我可能考虑提交一个PR。
-
Waline 组件的配置我只添加了必要的选项,后续可以参考 组件属性 | Waline 添加更多选项,尤其是 Challenge 相关配置,用于增强安全性。
-
Waline 的默认主题虽然挺好看的,但是与 Fuwari 略微有些不协调,暗色模式下更是糟糕。后续可以参考 自定义样式 | Waline 修改 Waline 样式,由于 Waline 的 css 文件是单独引用的,可以方便的深度定制样式。