基于Hexo框架的博客搭建——进阶篇

Hexo 架构逻辑:核心组件与工作流

Hexo 的架构可抽象为「输入→处理→输出」三层,核心组件通过事件驱动和钩子机制协同工作,整体流程如下:

1. 核心组件

  • 源文件系统(Source):存储博客的原始内容,包括:
    • 文章(source/_posts/ 下的 Markdown 文件)
    • 页面(source/ 下的独立 Markdown 或 HTML 文件)
    • 静态资源(图片、CSS、JS 等,存放于 source/ 子目录)
    • 配置文件(根目录 _config.yml、主题配置 _config.<theme>.yml
  • 处理器(Processors):负责解析和转换源文件,核心包括:
    • 解析器(Parsers):解析 Front-matter(YAML 元数据)、Markdown 内容、配置文件(使用 js-yaml 库)。
    • 渲染器(Renderers):将 Markdown 转换为 HTML(默认用 marked 库),将模板文件(EJS/Pug 等)与数据结合生成最终页面(依赖 hexo-renderer-ejs 等插件)。
    • 过滤器(Filters):在处理过程中修改内容(如自动给图片添加标签、替换链接格式),基于「钩子函数」实现。
  • 数据模型(Models):Hexo 内部维护的抽象数据结构,包括:
    • Post:文章对象(包含标题、日期、标签等属性)。
    • Page:页面对象(独立页面,如「关于页」)。
    • Tag/Category:标签和分类对象,用于构建归档页面。
  • 生成器(Generators):根据数据模型和模板,生成静态 HTML 文件,核心逻辑是:
    1. 读取数据模型(如所有文章、标签列表);
    2. 匹配主题中的模板文件(如 index.ejs 对应首页,post.ejs 对应文章详情页);
    3. 将数据注入模板,生成 public/ 目录下的静态 HTML。
  • 部署器(Deployers):将 public/ 目录下的静态文件部署到服务器、GitHub Pages 等平台(如 hexo-deployer-git 插件通过 Git 推送)。

2. 工作流程图

1
2
3
4
5
6
7
8
9
源文件(Markdown/配置)  
↓(解析)
Front-matter 元数据 + 内容文本
↓(渲染)
HTML 片段 + 数据模型(Post/Page 等)
↓(生成)
结合主题模板(EJS/Pug)→ 静态 HTML(public/)
↓(部署)
上传到服务器/托管平台

底层实现:技术栈与核心机制

Hexo 基于 Node.js 开发,核心依赖以下技术和机制:

1. 技术栈基础

  • 运行时:Node.js(利用其异步 I/O 特性高效处理文件读写)。
  • 依赖管理npm(通过 package.json 管理插件和主题依赖)。
  • Markdown 解析:默认用 marked 库,可通过插件替换为 hexo-renderer-markdown-it 等(支持更多语法)。
  • 模板引擎:默认支持 EJS,可通过插件扩展 Pug、Nunjucks 等(主题模板文件需对应引擎)。
  • YAML 解析:用 js-yaml 库解析 Front-matter 和配置文件(严格要求 YAML 语法,如冒号后必须有空格)。

2. 核心机制

  • 事件驱动与钩子(Hooks)
    Hexo 内部通过 hexo.extend 注册钩子,允许插件在特定阶段介入处理流程。例如:
    • before_generate:生成静态文件前触发(可用于动态添加数据)。
    • after_render:html:HTML 渲染完成后触发(可用于压缩 HTML)。
  • 插件系统
    所有功能(渲染器、生成器、部署器等)均通过插件实现,核心代码仅提供框架。例如:
    • 渲染 Markdown 需要 hexo-renderer-marked 插件;
    • 用 Git 部署需要 hexo-deployer-git 插件。
      插件通过 hexo.extend API 注册功能(如 hexo.extend.renderer.register 注册自定义渲染器)。
  • 缓存机制
    生成静态文件时,Hexo 会将解析后的元数据缓存到 db.json,避免重复解析未修改的文件(hexo clean 会清空缓存)。

内容创作

1. 新建文章 / 页面

1
2
3
4
5
6
# 新建文章(默认存到 source/_posts/ )
hexo new <title> # 如:hexo new "我的第一篇博客"
hexo new [layout] <title> # layout 可选 post(默认)、page、draft

# 高级用法:自定义路径(避免标题影响文件名)
hexo new page --path about/me "关于我" # 生成 source/about/me.md

2. 发布草稿

草稿存于 source/_drafts/,发布时移到 _posts

1
hexo publish [layout] <filename>  # 如:hexo publish draft "草稿名"  

3.识别文章

对于直接放入posts的md文件,需要添加Front-matter元数据:

  • Front-matter 是 Hexo 识别文章的「身份证」,必须放在 Markdown 文件的 最开头,用 --- 包裹,格式为 YAML 语法。

最少需要包含 2 个字段title(文章标题)和 date(发布日期),示例:

1
2
3
4
5
6
---
title: 这是我的文章标题
date: 2025-08-12 15:30:00 # 格式:年-月-日 时:分:秒
---

这里是文章正文(Markdown 格式)...

可选补充字段(让文章更规范)

除了必填的 titledate,还可以添加以下常用字段(按需选择):

1
2
3
4
5
6
7
8
9
10
---
title: 这是我的文章标题
date: 2025-08-12 15:30:00
categories: 技术笔记 # 文章分类(可多层,如:前端/JavaScript)
tags: [Hexo, 博客] # 文章标签(数组格式)
author: 你的名字 # 作者(如果主题支持显示)
description: 这是文章的简短描述 # 用于SEO或主题摘要显示
---

正文内容...

生成与预览

1. 生成静态文件

1
2
3
4
5
hexo generate  # 简写 hexo g,生成 public/ 目录(静态网页)  
# 可选参数:
# --watch 监听文件变化,自动重新生成
# --force 强制全量生成(忽略缓存,类似 hexo clean + hexo g)
# --deploy 生成后立即部署

2. 本地预览

1
2
3
hexo server  # 简写 hexo s,启动本地服务器(默认 http://localhost:4000 ) 
# 可选参数:
# --port 3000 # 修改端口(如避免4000冲突)

为什么要生成静态文件

Hexo 这类工具的设计目标是 “预先生成静态文件”,核心逻辑是:
在本地通过Markdown等源文件、模板引擎(如 EJS、Pug)和配置,预先渲染出所有页面的静态 HTML,然后将这些静态文件部署到服务器。

这种方式的优势是:

  • 性能极快:静态文件直接由服务器 / CDN 返回,无需数据库查询或后端计算,加载速度远快于动态生成。
  • 服务器成本低:静态文件可部署到轻量服务器、对象存储(如 S3、OSS)甚至纯 CDN,无需复杂的后端环境(如数据库Python/PHP运行时)。
  • 安全性高:没有后端代码和数据库,减少了SQL注入、脚本漏洞等风险。

什么情况下不需要生成静态文件?

如果你的网站需要 实时动态交互(如用户登录、评论互动、数据实时更新等),可能需要动态处理,此时无需预生成静态文件,常见场景:

  • 用 WordPress、Django、Flask 等动态框架开发的网站,直接部署后端代码和数据库,服务器实时处理请求。
  • 带用户系统、支付功能、实时数据展示的网站(如电商、社交平台),需要后端逻辑动态生成内容。

部署与配置(基于Alibaba Linux)

核心思路:

  1. 用 root 创建普通用户(避免 root 权限风险)
  2. 配置用户权限 + 免密 SSH(部署更方便)
  3. 服务器安装 Nginx 并配置网站目录权限
  4. 本地 Hexo 配置免密部署
  5. 一键发布博客

一、服务器端配置(VSCode 远程连接后操作)

1. 用 root 创建普通用户(关键:告别 root 操作)

1
2
3
4
5
6
7
8
# 1. 创建用户(比如用户名设为 hexo,可自定义)
useradd -m hexo
# 2. 设置密码(按提示输入,记好)
passwd hexo
# 3. 给hexo用户sudo权限(后续装软件需要)
usermod -aG wheel hexo # Alibaba Linux/CentOS 通用
# 4. 切换到hexo用户(后续所有操作都用这个用户)
su - hexo

2. 安装必备软件(hexo 用户下执行)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 1. 更新系统(可选,建议做)
sudo yum update -y

# 2. 安装Nginx(核心:提供静态网页访问)
sudo yum install -y nginx
# 启动Nginx + 设置开机自启
sudo systemctl start nginx
sudo systemctl enable nginx

# 3. 安装Git(核心:Hexo部署用)
sudo yum install -y git

# 4. 安装Node.js(可选:如果想在服务器调试Hexo,本地有则不用)
# 安装NodeSource源(Node.js 20.x,稳定版)
curl -fsSL https://rpm.nodesource.com/setup_20.x | sudo bash -
# 安装Node.js
sudo yum install -y nodejs
# 验证安装
node -v # 输出v20.x.x即成功
npm -v # 输出9.x.x即成功

此处注意,轻量云服务器易出现内存不足无法update的情况

临时增加交换内存(解决内存不足,可选)

如果想坚持更新系统,先给服务器加临时交换内存(重启后失效,不占磁盘长期空间):

1
2
3
4
5
6
7
8
9
10
11
12
13
# 1. 用root用户(或hexo用户加sudo)创建1G交换文件
sudo fallocate -l 1G /swapfile
# 2. 设置权限(只有root能访问)
sudo chmod 600 /swapfile
# 3. 格式化交换文件
sudo mkswap /swapfile
# 4. 启用交换内存
sudo swapon /swapfile
# 5. 再次执行更新(此时内存足够,不会被Killed)
sudo yum update -y
# 6. 更新完成后,可选关闭交换内存(节省资源)
sudo swapoff /swapfile
sudo rm -f /swapfile

3. 配置 Nginx 网站目录(关键:权限安全)

1
2
3
4
# 1. 创建博客根目录(用hexo用户创建,避免权限问题)
mkdir -p /home/hexo/blog/public
# 2. 设置Nginx默认目录指向这个文件夹(修改配置文件)
sudo vim /etc/nginx/nginx.conf

修改 nginx.conf 关键内容(找到 location / 所在的 server 块):

1
2
3
4
5
6
7
8
9
server {
listen 80 default_server;
listen [::]:80 default_server;
# 把root路径改成下面这行
root /home/hexo/blog/public;
index index.html index.htm;

# 保留其他配置,只改root即可
}
1
2
3
4
# 3. 重启Nginx生效配置
sudo systemctl restart nginx
# 4. 验证Nginx配置(无报错即成功)
sudo nginx -t

4. 配置免密 SSH(可选但强烈推荐:部署不用输密码)

a.本地生成 SSH 密钥对

1
2
3
# Windows PowerShell 执行
ssh-keygen -t ed25519 -C "你的邮箱"
# 一路回车(无需设置密码),密钥生成在 C:\Users\你的用户名\.ssh\ 下

b.服务器配置免密登录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 1. 登录服务器(首次需输密码)
ssh hexo@服务器公网 IP

# 2. 创建 .ssh 目录并设置权限
mkdir -p ~/.ssh
chmod 700 ~/.ssh

# 3. 本地推送公钥到服务器(新开本地 PowerShell)
type $env:USERPROFILE\.ssh\id_ed25519.pub | ssh hexo@服务器 IP "cat >> ~/.ssh/authorized_keys"

# 4. 服务器设置授权文件权限
chmod 600 ~/.ssh/authorized_keys

# 5. 验证免密登录(本地执行,无需输密码即为成功)
ssh hexo@服务器 IP

5.配置 Git 裸仓库 + 钩子脚本

a.创建 Git 裸仓库(仅存储代码,无工作目录)

1
2
3
4
5
6
7
# 服务器 hexo 用户执行
# 删除旧的无效目录
rm -rf /home/hexo/blog/public

# 创建裸仓库
mkdir -p /home/hexo/blog
git init --bare /home/hexo/blog/hexo-blog.git

b.配置 post-receive 钩子脚本(自动同步文件到 Nginx 目录)

1
2
# 编辑钩子脚本
vim /home/hexo/blog/hexo-blog.git/hooks/post-receive

粘贴以下内容(按 i 进入插入模式):

1
2
3
4
5
6
7
8
9
#!/bin/bash
# 定义 Nginx 读取的静态文件目录
PUBLIC_DIR=/home/hexo/blog/public
# 清空旧文件
rm -rf ${PUBLIC_DIR}/*
# 切换到临时目录避免工作目录问题
cd /tmp
# 从裸仓库导出静态文件到 PUBLIC_DIR
git --work-tree=${PUBLIC_DIR} --git-dir=/home/hexo/blog/hexo-blog.git checkout -f master

保存退出(Esc:wq),设置脚本可执行:

1
chmod +x /home/hexo/blog/hexo-blog.git/hooks/post-receive

c.修复目录权限(避免 Nginx 403 错误)

1
2
3
4
5
6
7
8
# 创建 public 目录
mkdir -p /home/hexo/blog/public

# 确保 Nginx 能读取文件
chmod o+x /home/hexo
chmod o+x /home/hexo/blog
sudo chown -R nginx:nginx /home/hexo/blog/public
sudo chmod -R 755 /home/hexo/blog/public

二、本地Hexo配置+一键部署

1. 修改 Hexo 部署配置

打开本地 Hexo 博客根目录的 _config.yml,修改 deploy 模块:

1
2
3
4
5
deploy:
type: git
repo: hexo@服务器 IP:/home/hexo/blog/hexo-blog.git # 指向裸仓库
branch: master
key: C:\Users\你的用户名\.ssh\id_ed25519 # 可选,指定私钥路径

注意:YAML 格式要求冒号后加空格(如 type: git)。

2. 安装部署插件(首次需装)

1
2
# 本地 Hexo 目录执行
npm install hexo-deployer-git --save

3. 一键部署博客

1
2
# 清空缓存 → 生成静态文件 → 部署到服务器
hexo clean && hexo generate && hexo deploy

✅ 成功标志:终端显示 INFO Deploy done: git

4.服务器手动触发钩子(首次部署后)

1
2
3
4
5
6
# 服务器执行,确保文件同步到 public 目录
cd /tmp
/home/hexo/blog/hexo-blog.git/hooks/post-receive

# 验证文件是否生成
ls -la /home/hexo/blog/public # 有 index.html、css 等文件即为成功

三、其他部署方式

将本地生成的静态文件上传到服务器:

  1. 方法一:使用 VSCode 的文件传输功能

    • 在 VSCode 左侧资源管理器中找到本地 Hexo 项目的public文件夹
    • 右键点击该文件夹,选择 “上传到远程”
    • 上传到服务器的/var/www/hexo-blog目录下
  2. 方法二:使用命令行 scp 工具(在本地终端执行)

    1
    scp -r /本地Hexo路径/public/* 用户名@服务器IP:/var/www/hexo-blog/

四、Nginx 配置 + 域名绑定

1.修改 Nginx 主配置

1
sudo vim /etc/nginx/nginx.conf

2.修改 server 块核心内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
server {
listen 80;
listen [::]:80;
server_name blog.hellozhw.cn; # 绑定你的域名
root /home/hexo/blog/public; # 博客文件目录
index index.html index.htm;

# 保留原有 include/error_page 配置
include /etc/nginx/default.d/*.conf;
error_page 404 /404.html;
location = /40x.html {}
error_page 500 502 503 504 /50x.html;
location = /50x.html {}
}

3.保存退出,验证配置并重启 Nginx:

1
2
sudo nginx -t  # 语法检查
sudo systemctl restart nginx # 重启生效

五、配置 HTTPS(Let’s Encrypt 免费证书)

1.安装 Certbot 工具

1
2
# 阿里云 Linux 执行
sudo yum install -y certbot python3-certbot-nginx

2.一键生成并安装证书

1
sudo certbot --nginx -d blog.hellozhw.cn

按交互提示操作:

  1. 输入邮箱 → 回车;
  2. 输入 Y 同意条款 → 回车;
  3. 输入 N 拒绝共享邮箱 → 回车;
  4. 输入 2 强制 HTTP 跳转到 HTTPS → 回车。

3. 配置证书自动续期(永久有效)

1
2
# 编辑定时任务
sudo crontab -e

添加以下内容(每天凌晨自动续期):

1
0 0 * * * /usr/bin/certbot renew --quiet

保存退出,验证定时任务:

1
sudo crontab -l  # 能看到上述行即为成功

4. 验证 HTTPS 生效

1
2
3
4
5
# 服务器本地测试
curl -I https://blog.hellozhw.cn

# 浏览器验证
# 访问 https://blog.hellozhw.cn 显示小锁图标,HTTP 自动跳转 HTTPS