简介

Hexo 是一款基于 Node.js 的静态博客框架。它通过解析 Markdown 文章生成静态网页。只需要将 Hexo 生成的文件托管到平台上,即可完成博客的部署。

Hexo 的主题包丰富而优秀,其中使用者最多的主题为 NexT,本文将使用该主题搭建博客。

有精力更深入探索的同学可以自行阅读 Hexo 和 NexT 的官方文档,以获得更全面的了解。

安装与配置本地环境

前置准备

我们需要在本地安装 Node.js,用于提供 JavaScript 运行环境,并提供 npm 包管理器用于安装 Hexo 的命令行界面、NexT 主题和相关插件。

如果我们想从 GitHub 下载主题,或者希望把博客部署到服务器或 GitHub,那么我们还需要安装 Git 来进行文件传输。

如果想要获得 Hexo 的最佳使用体验,那么建议使用 Visual Studio Code 来进行开发。

初始化

确认本地有 Node.js 环境后,我们首先安装 Hexo 的命令行界面(Command line interface),然后在自己指定的目录下初始化 Hexo,并进入博客文件夹中。

1
2
3
npm install hexo-cli -g
hexo init hexo-blog
cd hexo-blog

这里推荐使用 Visual Studio Code 来帮助管理博客,当然只使用命令行也可以完成 Hexo 博客的全流程配置,Visual Studio Code 只用于简化操作。

认识命令

现在我们已经得到了一个初始的 Hexo 博客。让我们先认识一下调试 Hexo 的一些命令,再对博客进行个性化配置。

  • hexo clean: 清除生成的静态文件和缓存;
  • hexo generate: 生成静态文件,可以简写为 hexo g
    • hexo generate -d: 生成静态文件后将其部署,相当于 hexo generate && hexo deploy,可以简写为 hexo g -d
  • hexo server: 启动网站服务,此时可以在浏览器中访问网站,可以简写为 hexo s
    • hexo server --port [port]: 指定服务端口,可以简写为 hexo s -p [port]
    • hexo server --open: 启动服务后立即在本机默认浏览器中打开网站,可以简写为 hexo s -o
  • hexo deploy: 用于部署静态文件到远端服务器或平台,可以简写为 hexo s -o
    • hexo deploy -g: 部署前生成静态文件,相当于 hexo generate && hexo deploy,可以简写为 hexo d -g

看似命令很多,实际上我们只需要用到两个组合命令。

  • preview: hexo clean && hexo generate && hexo server --open: 重新生成静态文件后启动网站服务并打开浏览器预览网页。
  • release: hexo clean && hexo generate && hexo deploy: 重新生成静态文件后部署到远端服务器或平台。

读者们可以尝试在本地运行一下 preview 命令,浏览器将自动打开 localhost:4000,你将看到你的初始博客的样子。

配置站点

站点的配置文件为博客文件夹下的 _config.yml 文件。我们可以通过修改该文件来完成站点的配置。

.yml 文件对应了标记语言 YAML,用来表达数据序列化。在后面我们还会看到 .json 文件,功能和 .yml 接近,只是采用了不同的标记语言,所以格式不同。

注意:修改站点的配置文件后,需要重新运行 preview 命令才能看到站点的更改。

安装与配置主题

安装主题

在旧版 Hexo 中,我们需要从 GitHub 将主题仓库 Clone 到本地,放置在 Hexo 的 theme 文件夹下。这样一来整个主题对于用户来说都是透明的,我们可以自由修改主题文件夹内的任何文件来获得我们想要的主题效果。但同时也带来了一些让人头疼的问题,其中最关键的问题是,NexT 主题更新非常频繁,而如果我们想要让自己的主题保持最新,则需要不断与 GitHub 同步。这样我们很容易让自己对 NexT 的修改与仓库的某处改动产生冲突,有时需要手动 Merge,这实在是太麻烦了。

在新版 Hexo 中,我们有一个新方案来安装主题,即使用包管理。我们可以使用 NPM 或者 Yarn 来将主题作为一个 JavaScript 包进行安装,参考 Installation | NexT

1
2
3
4
# Installed through npm
npm install hexo-theme-next
# Installed through yarn
yarn add hexo-theme-next

配置主题

Hexo 的初始主题为 LandScape,我们对 _config.yml 进行修改,即可切换到 NexT 主题。

1
theme: next

读者们可以运行 preview 命令来查看 NexT 主题的样子。

与 Hexo 一样,NexT 主题的配置也依靠 _config.yml 文件。但是注意站点和主题的配置文件不是同一个文件,站点配置文件位于博客文件夹根目录下,而主题配置文件位于主题文件夹下。如果主题是通过 Git 安装的,那么主题配置文件位于 theme\next 文件夹中。如果是通过包管理安装的,那么主题配置文件位于 node_modules/hexo-theme-next/ 文件夹中。

我们将主题配置文件复制到博客根目录,命名为 _config.next.yml,然后对该文件进行修改即可,参考 Configuration | NexT

1
2
3
4
# Installed through npm or yarn
cp node_modules/hexo-theme-next/_config.yml _config.next.yml
# Installed through Git
cp themes/next/_config.yml _config.next.yml

配置插件

有些功能是 Hexo 没有默认集成的,需要我们手动安装插件并启用,这里介绍一些常用的功能及其对应的插件。

数学公式

插件名:hexo-renderer-pandoc

当我们想要在博文中嵌入数学公式时,一个简单的做法是直接插入图片,但这样效率太低,且难以维护,我们可以安装插件来启用 \(\LaTeX\) 支持。不论是行内公式还是行间公式,都可以用一串简单的符号来表达。

Hexo 默认使用 hexo-renderer-marked 来进行渲染,但这个插件会导致 Markdown 标记和部分数学公式冲突,而 hexo-renderer-pandoc 则可以完美渲染。

注意:若需要使用 hexo-renderer-pandoc,除了安装插件,还需要本地安装 Pandoc。参考:Math Equations | NexT

1
2
3
4
5
6
# Installed through npm
npm uninstall hexo-renderer-marked
npm install hexo-renderer-pandoc
# Installed through yarn
yarn add hexo-renderer-marked
yarn add hexo-renderer-pandoc

我们还需要在 _config.next.yml 文件中进行修改。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# Math Formulas Render Support
# Warning: Please install / uninstall the relevant renderer according to the documentation.
# See: https://theme-next.js.org/docs/third-party-services/math-equations
# Server-side plugin: https://github.com/next-theme/hexo-filter-mathjax
math:
# Default (false) will load mathjax / katex script on demand.
# That is it only render those page which has `mathjax: true` in front-matter.
# If you set it to true, it will load mathjax / katex script EVERY PAGE.
every_page: true

mathjax:
enable: true
# Available values: none | ams | all
tags: all

katex:
enable: false
# See: https://github.com/KaTeX/KaTeX/tree/master/contrib/copy-tex
copy_tex: false

数据检索

插件名:hexo-generator-searchdb

专为 NexT 开发的数据检索插件,可以在侧边栏中看到一个检索按钮,点击即可弹出数据检索框。

1
2
3
4
# Installed through npm
npm install hexo-generator-searchdb
# Installed through yarn
yarn add hexo-generator-searchdb

我们还需要在 _config.next.yml 文件中进行修改。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# ---------------------------------------------------------------
# Search Services
# See: https://theme-next.js.org/docs/third-party-services/search-services
# ---------------------------------------------------------------

# Local Search
# Dependencies: https://github.com/next-theme/hexo-generator-searchdb
local_search:
enable: true
# If auto, trigger search by changing input.
# If manual, trigger search by pressing enter key or search button.
trigger: auto
# Show top n results per article, show all results by setting to -1
top_n_per_article: -1
# Unescape html strings to the readable one.
unescape: true
# Preload the search data when the page loads.
preload: false

字数统计

插件名:hexo-word-counter

专为 NexT 开发的字数统计插件,可以在每一篇文章的标题下显示字数,并在博客页脚处显示整个博客的总字数。

1
2
3
4
# Installed through npm
npm install hexo-word-counter
# Installed through yarn
yarn add hexo-word-counter

我们还需要在 _config.next.yml 文件中进行修改。

1
2
3
4
5
# Post wordcount display settings
# Dependencies: https://github.com/next-theme/hexo-word-counter
symbols_count_time:
separated_meta: true
item_text_total: true

远端部署

插件名:hexo-deployer-git

Hexo 官方提供的基于 Git 的部署插件,安装该插件后才可以使用 hexo deploy 命令。

1
2
3
4
# Installed through npm
npm install hexo-deployer-git
# Installed through yarn
yarn add hexo-deployer-git

我们还需要在 _config.yml 文件中进行修改。

1
2
3
4
5
6
7
8
# Deployment
## Docs: https://hexo.io/docs/one-command-deployment
deploy:
type: git
repo:
tencent: git@0xfaner.top:/home/git/repos/blog.git
github: git@github.com:0xfaner/0xfaner.github.io.git
branch: master

更多细节可以参考下文关于部署的介绍。

使用技巧

平时我们要经常组合使用这些命令,但是在命令行中敲写命令还是稍慢,我们可以利用 Visual Studio Code 帮助运行脚本,在博客文件夹中找到 package.json 文件,添加两条脚本:

  • preview: hexo clean && hexo generate && hexo server --open: 重新生成静态文件后启动网站服务并打开浏览器预览网页。
  • release: hexo clean && hexo generate && hexo deploy: 重新生成静态文件后部署到远端服务器或平台。
1
2
3
4
5
6
7
8
9
"scripts": {
"build": "hexo generate",
"clean": "hexo clean",
"deploy": "hexo deploy",
"server": "hexo server"
"server": "hexo server --open",
"preview": "hexo clean && hexo generate && hexo server --open",
"release": "hexo clean && hexo generate && hexo deploy"
},

然后我们可以在 Visual Studio Code 的 Explorer 框中找到 NPM scripts 栏(找不到的话可以在 Explorer 右键菜单中勾选让它显示),点击相应条目的 run 按钮即可快捷运行相应脚本。

相关问题

解决冲突

本文写作时 Node.js 的长期支持版(Long Term Support)已经更新到 16.13.0 了,Hexo 也更新到 5.4.0 了,但是运行 hexo g 等命令时,我们会发现 Hexo 会发出警告。

1
2
3
4
5
6
7
(node:10544) Warning: Accessing non-existent property 'lineno' of module exports inside circular dependency
(Use `node --trace-warnings ...` to show where the warning was created)
(node:10544) Warning: Accessing non-existent property 'column' of module exports inside circular dependency
(node:10544) Warning: Accessing non-existent property 'filename' of module exports inside circular dependency
(node:10544) Warning: Accessing non-existent property 'lineno' of module exports inside circular dependency
(node:10544) Warning: Accessing non-existent property 'column' of module exports inside circular dependency
(node:10544) Warning: Accessing non-existent property 'filename' of module exports inside circular dependency

经过检查,可以发现是 Hexo 用到的 NPM 包 stylus0.54.5 版本和 Node.js 的版本不兼容。选择降低 Node.js 的版本到 v12 可以消除警告,但是这非常不优雅,其实只需要升级本地的 stylus 包到 0.54.8 版本即可。

有些使用了 stylus 包的插件已经停止维护很久了,我们很难手动修改这些插件的配置,但是我们可以使用另一个 JavaScript 包管理器 Yarn 来帮助我们强制指定 stylus 的版本。

首先我们在博客文件夹中找到 package.json 文件,添加限定 stylus 包的版本信息。

1
2
3
"resolutions": {
"stylus": "^0.54.8"
}

然后我们安装 Yarn,并使用 Yarn 重新安装本地包,即可消除警告。

1
2
npm install -g yarn
yarn install

注意:不要混用包管理,如果我们使用了 Yarn,接下来博客中所有的插件都需要使用 Yarn 而不是 NPM 来安装,安装命令形如:

1
yarn add package-name

部署到 GitHub

前置准备

我们需要在 GitHub 注册一个账号,并在本地安装 Git 来将本地生成的静态文件部署到 GitHub Pages。

配置 GitHub

GitHub 是世界上最大最先进的代码托管平台,当我们注册完账号,可以将自己的代码托管在 GitHub 中。同时 GitHub 提供了 GitHub Pages 的服务,它是一个静态站点托管服务,直接从 GitHub 上的存储库中获取 HTML、CSS 和 JavaScript 文件,并生成网站。

我们先在 GitHub 中创建一个名为 0xfaner.github.io 的仓库(注意开头必须为自己 GitHub 账号的 username 而不是 nickname

然后我们配置本地的 Git 的用户名和邮箱。

1
2
git config --global user.name "0xfaner"
git config --global user.email "0xfaner@gmail.com"

接着我们生成密钥。

1
ssh-keygen -t rsa -C "0xfaner@gmail.com"

生成过程中会需要我们输入三次信息,分别是需要保存密钥的位置,密钥的密码和重复密钥的密码,我们无需理会,全部回车跳过即可。

密钥的位置默认保存在 ~\.ssh\ 文件夹中,其中私钥是 id_rsa 文件,公钥是 id_rsa.pub 文件。

我们复制公钥的内容,加入到 GitHub 账号的 SSH Key 中,即可让本机的 Git 获得操作仓库的权限。

1
cat ~\.ssh\id_rsa.pub | clip

使用该命令可以快捷复制公钥内容。访问网页 https://github.com/settings/ssh/new 即可快捷为 GitHub 账户添加 SSH 密钥,将公钥的内容粘贴到 Key 框中,Title 可以随意命名,点击 Add SSH key 即可完成 SSH 密钥的添加。

此时我们已经完成了 GitHub 的配置,我们只需要在本地配置好 Hexo 的相关设置即可。

配置本地 Hexo

具体配置详见前文的远程部署

部署到服务器

前置准备

本地需要安装 Git 来将本地生成的静态文件部署到服务器。

服务器中需要安装 Git 和 Nginx,分别用于接受静态文件,和建立网站服务,本文中服务器系统为 CentOS。

配置流程

配置本地 Git

首先配置本地 Git 的用户名和邮箱。

1
2
git config --global user.name "0xfaner"
git config --global user.email "0xfaner@gmail.com"

接着我们生成密钥。

1
ssh-keygen -t rsa -C "0xfaner@gmail.com"

生成过程中会需要我们输入三次信息,分别是需要保存密钥的位置,密钥的密码和重复密钥的密码,我们无需理会,全部回车跳过即可。

密钥的位置默认保存在 ~\.ssh\ 文件夹中,其中私钥是 id_rsa 文件,公钥是 id_rsa.pub 文件。

配置服务器 Git

首先使用包管理安装 Git。

1
yum install -y git

然后查看 Git 是否安装完成。

1
git --version

出于安全考虑,我们新建一个名为 git 的用户,专门用于接受静态文件。

1
2
useradd git
passwd git

然后我们切换到 git 用户。

1
su git

然后我们分别配置 Git 仓库的路径和静态文件的路径。Git 仓库目录在 /home/git/repos/blog.git ,静态文件部署在 /home/git/projects/blog

1
2
3
4
cd /home/git/
mkdir -p projects/blog
mkdir repos && cd repos
git init --bare blog.git

我们需要配置 Git,利用 post-receive 实现自动化部署。

1
2
cd blog.git/hooks
vim post-receive

输入内容如下(不了解文本编辑器 Vim 操作的用户需要自行了解一下)。

1
2
#!/bin/sh
git --work-tree=/home/git/projects/blog --git-dir=/home/git/repos/blog.git checkout -f

然后配置可执行权限。

1
2
3
chmod +x post-receive
exit
chown -R git:git /home/git/repos/blog.git

然后我们测试一下仓库是否成功配置,在本地运行命令尝试将远端仓库 Clone 下来。

1
git clone git@0xfaner.top:/home/git/repos/blog.git

如果能够把空仓库拉下来就说明配置完成。

然后我们建立 SSH 信任关系:

注意ssh-copy-id 需要使用 Git Bash 执行。

1
2
ssh-copy-id -i ~/.ssh/id_rsa.pub git@0xfaner.top
ssh -T git@0xfaner.top

如果不需要密码而成功登陆了,那么说明配置完成,运行命令 logout 即可退出登录。

安全起见,修改 /etc/passwd 文件,让 git 用户默认使用 Git Shell,这样它就只能使用 git clonegit push 等命令。

1
2
- git:x:1000:1000::/home/git:/bin/bash
+ git:x:1000:1000:,,,:/home/git:/usr/bin/git-shell

配置 Nginx

首先安装 Nginx。

1
yum install -y nginx

然后查看 nginx 是否安装完成。

1
nginx -v

安装完成后,启动 Nginx。

1
nginx

然后访问自己服务器的IP或域名来看看效果,如果无法访问,那么需要检查下服务器防火墙以及云服务器商的安全组策略。

修改 Nginx 的配置文件 nginx.conf,一般目录为 /etc/nginx/nginx.conf

1
vim /etc/nginx/nginx.conf

如果目录位置不对,那么寻找一下 Nginx 的安装位置。

1
whereis nginx

根据显示的目录找一下。

将其中的 user 从默认的 nginx 改为 gitroot 以确保访问权限,防止出现 403 Forbidden 的无权限错误。

同时将根目录修改为静态文件所在的目录。

1
2
3
4
5
6
7
8
9
10
11
12
13
- user nginx;
+ user git;
# ...
http {
# ...
server {
# ...
- root /usr/share/nginx/html/;
+ root /home/git/projects/blog;
# ...
}
# ...
}

修改完成后,重启 Nginx 即可。

1
nginx -s reload

配置本地 Hexo

具体配置详见前文的远程部署

使用技巧

开启HTTPS

首先需要获取一份证书,可以使用 Let's Encrypt 的免费证书或在阿里云等服务商处代为申请。

因为是纯静态博客,所以也不需要用 Certbot 等工具进行一键 HTTPS 配置,直接在 Nginx 里面加载证书就行。

首先将证书传输到服务器中,包括 .pem.key 两个文件。

然后将 nginx.conf 文件中的 HTTPS 部分取消注释,修改根目录,并配置证书路径。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
user git;
# ...
http {
# ...
server {
# ...
root /home/git/projects/blog;
# ...
}
# ...
server {
# ...
- root /usr/share/nginx/html/;
+ root /home/git/projects/blog;
- ssl_certficate "old_path";
+ ssl_certficate "new_path";
- ssl_certficate_key "old_path";
+ ssl_certficate_key "new_path";
# ...
}
# ...
}

修改完成后,重启 Nginx 即可。

1
nginx -s reload

即可完成配置。

HTTP强制跳转HTTPS

如果希望访问都以 HTTPS 方式,那么需要配置 HTTP 强制跳转 HTTPS。修改 nginx.conf 文件即可。

从下面两段代码中任选一段:

1
2
3
if ($scheme = http) {
return 301 https://$host$request_uri;
}
1
2
3
if ($server_port = 80) {
return 301 https://$host$request_uri;
}

插入到代码中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
user git;
# ...
http {
# ...
server {
# ...
root /home/git/projects/blog;
# 这里这里这里
# ...
}
# ...
server {
# ...
root /home/git/projects/blog;
ssl_certficate "new_path";
ssl_certficate_key "new_path";
# ...
}
# ...
}

修改完成后,重启 Nginx 即可。

1
nginx -s reload

后记

废了不少时间重建博客重写博文,希望赋闲在家的一年里可以不用再折腾这个博客了(哭