问题描述

博主最近闲的没事又在摆弄博客,想着给博客加个评论系统,butterfly本身集成了不少评论系统,只要在配置里面配一下就好了:

1
2
3
4
5
6
7
8
9
10
comments:
# Up to two comments system, the first will be shown as default
# Choose: Disqus/Disqusjs/Livere/Gitalk/Valine/Waline/Utterances/Facebook Comments/Twikoo/Giscus/Remark42/Artalk
use: Gitalk # Valine,Disqus
text: true # Display the comment name next to the button
# lazyload: The comment system will be load when comment element enters the browser's viewport.
# If you set it to true, the comment count will be invalid
lazyload: false
count: false # Display comment count in post's top_img
card_post_count: false # Display comment count in Home Page

我看腾讯云的那个评论系统用的人挺多的,但是考虑腾讯云在国内,搞不好谁乱评论,结果我背锅被拷走了,所以我还是想换一个,筛选了一下发现Gitalk很不错,基于Githubissue系统,集成进入博客以后跟踪issue确实跨域方便很多,看看GitalkGithub主页,用起来其实也很简单,更何况butterfly已经集成的差不多了,直接Github申请个oauth2第三方应用就行了,申请点这里

image-20240408112036382

注意回调链接和主页面链接写你的博客网站就行了就行了,这个具体的配置原理应该也就是刚才说的oauth2了。

之后改butterfly的配置文件就好了:

1
2
3
4
5
6
7
gitalk:
client_id: c2e02f1625dd3048e2af
client_secret: 不给你看
repo: echo-xzp.github.io
owner: echo-xzp
admin: echo-xzp
option:

仓库名就是你要集成issue的仓库,owneradmin写自己的用户名就行了,具体配置其实参照Gitalk的官方文档更加详细。

现在貌似配的都差不大了,直接推送部署,结果发现就有问题了:点击登录Github的时候一直加载,最后直接超时报错了。

问题分析

由于众所周知的原因,登录Github是经常性的抽风,大抵这就是超时的原因了。开代理后再次尝试,发现一点问题没有了。

那么有没有方法解决这个问题呢?Githubissue就有提到,用代理请求的方式来获取,博主于是按照线索又是一顿搜索,最后找到了一个博主给出的具体解决方案,他还给了几种解决方法,看代码其实也就是用Koa 来中间转发一下请求,然后利用函数接口部署成一个在线服务,而博主的博客刚好又是在Vercle上的,于是理所当然的部署Vercle上了,部署可以参照那个博主的博客,给的十分的详细,部署其实也很简单,直接fork一下,Vercle直接导入项目在deploy就行了,不过由于域名污染的原因,必须要自定义一个域名才能正常访问接口。再改一下butterfly的配置:

1
2
3
4
5
6
7
8
9
gitalk:
client_id: c2e02f1625dd3048e2af
client_secret: 不给你看
repo: echo-xzp.github.io
owner: echo-xzp
admin: echo-xzp
proxy: https://cors-server.hitagi.icu/github_access_token
option:
proxy: https://cors-server.hitagi.icu/github_access_token

推送部署,发现这下没问题了:

image-20240408114733344

问题拓展

貌似都解决了,但是博主从一开始就感觉直接配置文件中写死Gitalksecret是十分不安全的,我的项目本身就是个公开仓库,这好比就是光着屁股天天跑,虽然我的Github也不值钱咯,但是总叫人心里不舒服。于是博主就想能不能把secret写进环境变量里面,然后在yaml里面直接引用就行了,以多年Spring中配置yaml的经验来看,是不是直接用个占位符就能实现?类似:

1
2
3
4
5
6
7
8
9
gitalk:
client_id: c2e02f1625dd3048e2af
client_secret: ${GITALK_TOKEN}
repo: echo-xzp.github.io
owner: echo-xzp
admin: echo-xzp
proxy: https://cors-server.hitagi.icu/github_access_token
option:
proxy: https://cors-server.hitagi.icu/github_access_token

推送一下,发现直接报错了,果然不行,于是博主一想,Spring里面明显是有专门的处理器来处理yaml的,自然而然那种方式就能实现了,但是现在的yamlnodejs完成编译,之后更是直接运行在浏览器里面了,那到底该如何替换呢?注定要光着屁股吗?

问题解决

回到刚才所说的,在hexo构建的时候是运行在nodejs里面的,那就大有文章可做了。首先我的项目推送上去的时候,是由vercleCI/CD替我完成构建的,具体也就是执行npm run build,直接在package.json看一下这个命令具体执行了啥:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"name": "hexo-site",
"version": "0.0.0",
"private": true,
"scripts": {
"build": "hexo clean && hexo generate",
"clean": "hexo clean",
"deploy": "hexo deploy",
"server": "hexo server",
"preview": "hexo clean && hexo g && hexo s"
},
"hexo": {
"version": "7.1.1"
},
}

不就是清除缓存再重新生成一遍页面吗?那按照这个思路可以在前面加一句让它在生成前先处理一下配置的yaml

按照这个思路,先在hexo根目录建立一个scripts文件夹,里面开始写处理yaml的脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// update-config.js
const fs = require('fs');
const yaml = require('js-yaml');

const update_config = () =>{
try {
// 读取Hexo配置文件
const configData = fs.readFileSync('_config.butterfly.yml', 'utf8');

// 解析YAML数据
const parsedConfig = yaml.load(configData);

// 修改你想要的变量,例如修改title
// GITALK_TOKEN是环境变量,要预先配置
parsedConfig.gitalk.client_secret = process.env.GITALK_TOKEN;

// 将修改后的配置转换回YAML格式
const newYaml = yaml.dump(parsedConfig);

// 将修改后的配置写回配置文件中
fs.writeFileSync('_config.butterfly.yml', newYaml, 'utf8');

console.log("Hexo配置文件已修改成功!");
} catch (err) {
console.error('修改Hexo配置文件时出现错误:', err);
}
}

module.exports = {
update_config,
}

注意这里面调用了第三方库,必须在hexo里面先安装好:

1
npm i js-yaml --save

然后再写个入口,再到入口里面调用刚才那个函数就好了:

1
2
3
4
5
6
7
const {update_config} = require('./update-config')

const main = () =>{
update_config();
}

main()

最后再修改一下构建命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"name": "hexo-site",
"version": "0.0.0",
"private": true,
"scripts": {
"build": "node scripts/index && hexo clean && hexo generate",
"clean": "hexo clean",
"deploy": "hexo deploy",
"server": "hexo server",
"preview": "hexo clean && hexo g && hexo s"
},
"hexo": {
"version": "7.1.1"
},
}

也就是加个:node scripts/index指令,轻轻松松解决。

最后就是刚才那个环境变量,node里面通过process.env.你的环境变量名能够直接获取,关键是要预先配置好,我的是部署在vercle里面,也就是往它里面配置就好了,具体做法是找到:你的project > Setting > Environment Variables,直接添加就好了,如下:

image-20240408121428553

值得说一点的是你更新环境变量后要重新部署项目才会生效,博主就是这里折腾了好久,都配置好了还报错,还以为我这种方法不行了,结果是我没有更新部署。

按照上面的几点一步一步来基本没啥问题了,推送部署,完全没啥问题了。

后记

博主在查看vercle构建日志的时候又发现一个奇怪的事情:

image-20240408121832594

看日志明显脚本被执行了几次,这就又有点奇怪了。于是博主进行了一系列测试,发现原来hexo每次执行命令的时候都会自动执行scripts底下暴露的函数。还找到一篇说明的博客,那么其实我的还能简化一下,packages.json都不要改:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"name": "hexo-site",
"version": "0.0.0",
"private": true,
"scripts": {
"build": "hexo clean && hexo generate",
"clean": "hexo clean",
"deploy": "hexo deploy",
"server": "hexo server",
"preview": "hexo clean && hexo g && hexo s"
},
"hexo": {
"version": "7.1.1"
},
}

完美解决。