Notes on Hexo
记录使用Hexo的Next主题搭建博客的过程和遇到的问题,传送门hexo troubleshooting,next troubleshooting.
Terminal
XSHELL - The Industry's Most Powerful SSH Client
XShell is a popular and straightforward network program designed to emulate a virtual terminal. While it's not beginner-friendly, experienced users find it easier to use. With this tool, you can use a specific computer to act as a terminal.
Remote - SSH: 好朋友推荐的VS Code插件, 安装后在
Remote Explorer
中添加并输入ssh userName@00.00.00.00
即可.The Remote - SSH extension lets you use any remote machine with a SSH server as your development environment. This can greatly simplify development and troubleshooting in a wide variety of situations.
博客环境部署
Hexo
Hexo需要
- 10.13以上的Node.js
- Git
安装Node.js的16.14.2版本时时, 官方nodesource/distributions命令无法安装,
可以先去Downloads下载后按照Installation的步骤安装,
步骤写得非常好! 先装nvm,
官方安装方法使用了curl
或者wget
,
可能都会出现网络问题, 直接clone后bash isntall.sh
即可,
随后nvm install 17.8.0
,
nvm ls
查看当前所有可用版本, nvm use 17`即可.
1 | nvm install node # "node" is an alias for the latest version |
使用npm安装hexo时报npm无权限的错. 解决方法见How to fix npm throwing error without sudo, 这在nvm安装node后自然解决.
注意Documentation中为了去除npx
的echo 'PATH="$PATH:./node_modules/.bin"' >> ~/.profile
语句要在npx hexo init blog
后,
cd blog
后运行.
最后一步为hexo init <folder>
.
Hexo的更新方式为更改package.json
中的版本号后npm update
.
另见How
can I upgrade hexo? #4572,
提到npm
的使用方法为npm i hexo@5.2.0
.
常用命令
1 | hexo version # 查看版本 |
Nginx
Nginx, stylized as NGIИX, is a web server that can also be used as a reverse proxy, load balancer, mail proxy and HTTP cache. The software was created by Igor Sysoev and publicly released in 2004. Nginx is free and open-source software, released under the terms of the 2-clause BSD license.
这一节感谢好朋友的两次帮助.
安装方式为:
1 | sudo apt update |
不知道有啥区别的常用命令:
1 | nginx -t # 验证配置 |
Server Configuration
在/etc/nginx/sites-enabled/default
中加入
1 | server { |
403 Forbidden
一般问题出在/etc/nginx/nginx.conf
第一行,
默认为www-data
, 最粗暴可以直接改成root
, 见配置 Hexo 之后, Nginx 报
403.
SSL Certificate
An SSL certificate is a digital certificate that authenticates a website's identity and enables an encrypted connection. SSL stands for Secure Sockets Layer, a security protocol that creates an encrypted link between a web server and a web browser.
– What is an SSL certificate – Definition and Explanation
现在www.yuchen.xyz
可以正常访问了,
但https://www.yuchen.xyz
还不行, 需要部署SSL证书.
我的证书在阿里云, 但要部署在腾讯云上,
遇到唯一不同在于我从阿里云下的证书只有
腾讯云的Nginx 服务器
SSL 证书安装部署文档详细介绍了证书文件的含义, 以及配置过程,
可以在腾讯云的SSL 证书和证书监控
SSLPod中分别查看证书和监控证书.pem
和key
,
然后在腾讯云/etc/nginx/sites-enabled/default
配置时要输入并放入crt
文件,
我把pem
输入并放入就可以了, 其他都一样, 没什么大问题.
open() "/run/nginx.pid" failed (13: Permission denied)
不知道为什么访问网页时候显示SSL证书不受信任,
进服务器后nginx -t
报错如下:
1 | ubuntu@VM-4-5-ubuntu:/etc/nginx$ nginx -t |
前面加sudo运行一下就好了, 见open() "/run/nginx.pid" failed (13: Permission denied), 运行结果如下:
1 | ubuntu@VM-4-5-ubuntu:/etc/nginx$ sudo nginx -t |
放图片与文件的位置
以NexT为例,
images
文件夹为node_modules/hexo-theme-next/source/images
,
uploads
文件夹为source/uploads
.
备案
在_config.next.yml
内填写, 详见Site
Beian Information.
1
2
3
4
5
6
7 footer:
beian:
enable: true
icp: 京ICP备 1234567890号-1
gongan_id: 1234567890
gongan_num: 京公网安备 1234567890号
gongan_icon_url: /images/beian.png
ICP
年代太久远, 忘了, 类似沪ICP备2020026897号-1
公安部
公安备案接入服务商如何填写?(网站接入信息)
个人网站网安备案时服务类型选什么:
服务类型不要选交互-个人博客
,
选非交互-www服务
否则会被打回.
访问量
LeanCloud
_post
中.md
文档名称修改后访问会归零, 但有方法合并数据; 主页和帖子里都显示访客- LeanCloud (China)
- theme-next/hexo-leancloud-counter-security
一通设置后hexo clean && hexo generate --deploy
可能会报错
1 | TypeError: Cannot read properties of undefined (reading 'log') |
从Hexo
静态博客升级指南中得知是hexo-leancloud-counter-security的bug,
我也懒得改文档,
按照官方给的TroubleShooting做了一次rm <blog directory>/source/leancloud.memo
然后又deploy了两次就莫名其妙好了.
合并数据步骤:
- 进入LeanCloud,
点击
Data Storage → Data → Counter
, 下载成.csv
, 然后删光历史的记录 (一定要删光, 否则会生成一条url
类似/2021/12/21/2021-12-21-note-on-gnn/
的数据, 而其原为/2021/12/21/note-on-gnn/
). - 先
rm source/leancloud.memo
再hexo clean && hexo g -d
(否则阅读数据不会自动生成), 如果出现上述错误甚至是Too many request
的报错就再执行hexo clean && hexo g -d
, 执行到没错为止. - 进入LeanCloud, 发现数据生成好了, 把访问数修改为记住的历史总访客数.
- 进入博客,发现访问数又回来啦:happy:.
不蒜子
只在帖子页显示访问量; 主页总浏览量换服务器后还能自动继承, 省事~
Emoji
Next文档中指向的next-theme/hexo-filter-emoji, 不知道为啥不行 (仅把, 使用crimx/hexo-filter-github-emojis即可, 安装方式为:smile:
转成了一个貌似是html表情字符串的东西)npm install hexo-filter-github-emojis --save
, 然后修改_config.yml
:1
2
3
4
5
6githubEmojis:
enable: true
className: github-emoji
inject: true
styles:
customEmojis:用hexojs/hexo-renderer-markdown-it中的
markdown-it-emoji
解决问题. 然而没怎么看文档, 上来就遇到ToC的问题, 不用了不用了😅.
显示数学公式
Next官方文档中提到了两种渲染引擎:MathJax和KaTeX,实测KeTeX效果不好,所以推荐使用MathJax。首先要安装Pandoc,此过程中可能会遇到问题。
Pandoc是由John MacFarlane 页面存档备份,存于互联网档案馆开发的标记语言转换工具,可实现不同标记语言间的格式转换,堪称该领域中的“瑞士军刀”。Pandoc使用Haskell语言编写,以命令行形式实现与用户的交互,可支持多种操作系统;Pandoc采用GNU GPL授权协议发布,属于自由软件。
- 在theme config文件中启用MathJax
1 | math: |
- 卸载hexo-renderer-marked.
1 | npm un hexo-renderer-marked |
- 安装pandoc和hexo-renderer-pandoc,
安装时可以使用
cat /proc/version
检查一下服务器架构, 我的是amd64
1 | wget https://github.com/jgm/pandoc/releases/download/2.10.1/pandoc-2.10.1-1-amd64.deb |
References
- https://theme-next.js.org/docs/third-party-services/math-equations.html?highlight=latex
- https://github.com/theme-next/hexo-theme-next/issues/1454
- Highlight Bash/shell code in Markdown files
博客自动部署
见Nginx + Hexo 实现博客备份、自动部署及全站https
创建
build.sh
1
2
3
4
5
git pull | tee build.sh
source /home/ubuntu/.nvm/nvm.sh;
nvm use 17 | tee -a build.log
npx hexo clean && npx hexo g -d | tee -a build.log先
bash
运行试试, 可能会报个无关紧要的错误1
2
3
4
5
6
7
8
9ubuntu@VM-4-5-ubuntu:~/blog$ bash build.sh
' is not a git command. See 'git --help'.
The most similar command is
pull
build.sh: line 3: $'\r': command not found
Now using node v17.8.0 (npm v8.6.0)
INFO Validating config
......问问了好朋友, 这是因为我的
build.sh
是Windows上写的, 有字符串的问题, 他说可以用VS Code右下角的LF切换, 不过我就Ubuntu上手打了一份, 问题不大.创建
hooks.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21[
{
"id": "blog",
"execute-command": "/home/ubuntu/blog/build.sh",
"command-working-directory": "/home/ubuntu/blog",
"trigger-rule":
{
"match":
{
"type": "payload-hash-sha1",
"secret": "password",
"parameter":
{
"source": "header",
"name": "X-Hub-Signature"
}
}
}
}
]使webhook常驻后台.若修改
hooks.json
想重启, 见Hook not found. Error #246, 使用到的命令如下1
2
3
4
5
6
7cd webhook-linux-amd64/
nohup ./webhook -hooks /home/ubuntu/blog/hooks.json -verbose > webhook.log 2>&1 & # 在/webhook-linux-amd64/目录下运行
jobs # 查看nohup中正在运行的程序
sudo netstat -peanut # Active Internet connections (servers and established)
ps -eafww | grep 12345 # what process has it
sudo kill 12345 # execute the kill
sudo kill -9 12345 # a more forceful kill配置在Github上配置Webhooks, 设置
Payload URL
为http://www.yuchen.xyz:9000/hooks/blog
, 设置Content type
为application/json
, 输入和hooks.json
对应的密码.Windows上写个脚本
push.bat
1
2
3
4git add -A
git commit -m "updated %date:~0,10% %time%"
git push
pause测试一下, 运行
push.bat
, 运行vim /home/ubuntu/webhook-linux-amd64/webhook.log
观察服务器端的运行日志, 若出现报错Permission denied
则给bash.sh
加权限, 命令为chmod +x the_file_name
, 见Permission denied when running .sh scripts.
Troubleshooting
文章目录 (Table of Contents, ToC) 点击后不跳转
提出于Chinese
TOC cannot jump #1537解决于中文目录无法跳转,英文可以跳转
#1543. 我这个问题是hexo-renderer-markdown-it导致的.
缺少tomorrow.css
.config.next.yml
中代码高亮设置tomorrow
报错Error: ENOENT: no such file or directory, open '/home/ubuntu/blog/node_modules/highlight.js/styles/tomorrow.css'
,
查看后发现其位于../highlight.js/styles/base16/tomorrow.css
中,
设置为/base16/tomorrow
也不行, 按照blog - hexo
NexT主题下配置和美化的方法设置.config.yml
中hightlight
中的auto_detect
为true
也不行,
暂时用monokai
吧.
因jsDelivr被墙导致博客无法加载
首先了解一下Content delivery network (CDN)是什么:
A content delivery network, or content distribution network (CDN), is a geographically distributed network of proxy servers and their data centers. The goal is to provide high availability and performance by distributing the service spatially relative to end users. CDNs came into existence in the late 1990s as a means for alleviating the performance bottlenecks of the Internet as the Internet was starting to become a mission-critical medium for people and enterprises. Since then, CDNs have grown to serve a large portion of the Internet content today, including web objects (text, graphics and scripts), downloadable objects (media files, software, documents), applications (e-commerce, portals), live streaming media, on-demand streaming media, and social media sites. 一个内容交付网络,或内容分发网络(CDN),是一个由代理服务器及其数据中心组成的地理分布网络。其目的是通过在空间上相对于终端用户分布服务,提供高可用性和性能。CDNs出现在20世纪90年代末,是缓解互联网性能瓶颈的一种手段,当时互联网开始成为人们和企业的关键任务媒介。从那时起,CDN已经发展到为今天互联网内容的很大一部分提供服务,包括网络对象(文本、图形和脚本)、可下载对象(媒体文件、软件、文档)、应用程序(电子商务、门户网站)、直播流媒体媒体、按需流媒体和社交媒体网站。
再了解一下jsDelivr是什么:
JSDelivr (stylized as jsDelivr) is a free public CDN for open-source projects. It can serve web files directly from the npm registry and GitHub repositories without any configuration.
该问题的来龙去脉详见jsdelivr被墙,hexo-next切换为自定义CDN.
官方声明参见CDN
error in China #18348. 若干备用链接见[Feature]
Add CDN for Chinese mainland #424.
解决方法为在_config.next.yml
使用自定义链接:
1 | vendors: |
SSL证书间歇性错误
遇到域名随机无法访问的问题, 上SSL Server Test测试结果一切正常. 好朋友教我查看了下域名指向, 发现出问题时指向我的老服务器ip, 上域名解析把指向其的两条删除就好了.
hexo next type: 'unknown block tag: endnote'
hexo g
后产生的报错,
这是由于Typora的格式与Hexo的不匹配导致到Next中的note
组件没有被正确识别,
目前已知要注意的书写规则有:
- 不要在list后紧跟代码块
Next Tag Plugins
Label
- default yellow
1 | {% label @default yellow %} |
- primary purple
1 | {% label primary@primary purple%} |
- success green
1 | {% label success@success green %} |
- info blue
1 | {% label info@info blue %} |
- warning orange
1 | {% label warning@warning orange %} |
- danger red
1 | {% label danger@danger red %} |
图片名称双重显示
按照 的格式贴图会显示双重图片名, 正确的方式是 , 也即将图片名称写入"title"中.
关于插入图片的具体方式可参考How
to Add Image to Hexo Blog Post, 以下列举了alt
,
path
, title
三个参数的含义:
alt
is alternate text, provides alternative information for the image if user cannot view it for some reason like slow connection, wrong path or user is using screen reader;path
is image file link, most important part;title
is tooltip text (optional), appears when cursor is floating over the image.
以下是三种贴图方式的对比, 分别使用空图和非空图展示效果:
-  , 在方括号内填入名称alt, 而path后省略名称, 会产生双重alt名称, 不是理想的贴图方式.
-  , 在方括号内省略名称, 而在path后加上带双引号的title, 是理想的贴图方式.
-  , 方括号和path后都加入图片名称, 也会产生双重名称, 不是理想的贴图方式.
代码高亮
使用shell, bash等给命令行代码高亮, 另见Highlight Bash/shell code in Markdown files.
代码高亮种类和样式见highlight.js.
为了让博客中贴出的命令行代码美观, 又保证复制后能直接运行, 需要对参数做换行对齐处理, 如下:
1
2
3
4
5
6bin\OpenPoseDemo.exe --image_dir my_test ^
--write_json output/ ^
--display 0 ^
--render_pose 0 ^
--face^
--hand另见PowerShell command over multiple lines.
node & nodejs
node & nodejs have different version
Look up Symbols
领英中添加博客链接无图片
想要把博客主页https://www.yuchen.xyz/加到个人主页上, 但主页头像不能被爬取到, 该问题的根本原因是/blog/public/index.html中没有设置meta property, 详见Making Your Website Shareable on LinkedIn, 一个例子如下
1 | <meta name="image" property="og:image" content="[Image URL here]"> |
设置后, 在Sharing Debugger上查看结果, 根据提示完善设置, 见hexo 加上 Open Graph. 在Post Inspector上检查并更新结果, 见LinkedIn not picking up og:image.
问题在于每次在服务器部署博客时, /blog/public/index.html都会重置.
目前的解决方式为: 手动完成meta property的设置, 在领英上检查并更新后, 将博客主页加到个人主页上, 期待领英爬取的图片可以长期保存在其服务器上, 直到博客中的图片更新后再重复以上步骤.
Comments - Gitalk
theme next-third party services-comments-gitalk
Gitalk comments plug-in tutorial
Hexo - Add Gitalk Comment
hexo clean
和hexo generate
时报错
Plugin load failed: %s hexo-filter-emoji
1 | ERROR { |
使用npm uninstall hexo-filter-emoji --save
后莫名其妙就好了,
另见Hexo迁移报错,
hexo
搭建/使用中遇到的问题总结
gitalk Related Issues not found
⭐登录报错/?error=redirect_uri_mismatch& #162, 就是因为文章标题有空格或中文, 文件名删了空格改为英文就好了.
hexo gitalk 报错 redirect_uri_mismatch
GitHub The redirect_uri MUST match the registered callback URL for this application. #174
gitalk报错问题
Related Issues not found Please contact @someone to initialize the comment #87
gitalk Error: Request failed with status code 403
在授权gitalk后出现403错误 #429
➡Gitalk 评论登录 403 问题解决
在
themes/next/layout/_third-party/comments/gitalk.swig
中添加行proxy : '{{ theme.gitalk.proxy }}',
在
themes/next/_config.yml
中添加行proxy: https://netnr-proxy.cloudno.de/https://github.com/login/oauth/access_token
可用代理:
https://netnr-proxy.cloudno.de/https://github.com/login/oauth/access_token
https://cors-anywhere.azm.workers.dev/https://github.com/login/oauth/access_token
图床迁移
Gitee屏蔽外链, jsDelivr被墙, 免费稳定图床基本不用想了,
这里写了个Python脚本简单处理图片的文本替换,
以应对未来可能平凡迁移图片的情况.
注意这里能替换的只有形如
格式的图片,
暂时没有考虑html格式的图片. 参考了如下问题:
- UnicodeDecodeError:'gbk' codec can't decode byte 0x80 in position 0 illegal multibyte sequence: 读取带中文字符的文件
- Regex to parse image link in Markdown: 目标图片格式的正则表达式
- Splitting on
last delimiter in Python string?:
使用
rpartition()
以最后一个目标字符为界线分割字符串
1 | import os |