Hexo+GitHubPages搭建静态博客

本文最后更新于 2025年5月20日 上午

本人搭建博客是为了能在网站上浏览自己的记录。

博客的搭建参考了很多文章。其中,Hexo+Fluid搭建个人博客网站 这篇博文结构简单且思路清晰,在搭建初期很有帮助。在本博文开头,先对网络上知名或不知名的作者表示由衷的感谢:

  1. 文档 | Hexo:官方文档虽然不够细致,搜索引擎也是稀烂,但是如果有部分困惑,还是推荐查看。
  2. Hexo+Fluid搭建个人博客网站:简明!
  3. 彻底搞懂如何使用Hexo+GitHubPages搭建个人微博
  4. GitHub+Hexo 搭建个人网站详细教程
  5. 浅析 Hexo 搭建博客的原理 - 知乎
  6. 《A Guide Of Making Your Personal Blog》 系列文章
  7. hexo博客博文撰写篇之完美笔记大攻略终极完全版 | 夜法之书:全!
  8. ……

本博文将介绍如何从零开始,一步一步搭建出属于自己的个人博客网站。使用到的有 Hexo、Git、Fluid、GitHub 和 Github Pages。

  • Hexo:一个快速、简洁且高效的博客框架。 它能够解析 Markdown 文档(或其他标记语言),渲染成 HTML 静态网页(带有特色主题样式) 。
  • Git:分布式版本控制系统。建立本地仓库,管理本地数据。如果博客不需要细致地管理数据,一般只用到 Git 的 clone 和 push 功能,且这部分由 Hexo 命令完成。(不备份数据还是人类吗?我请问了!)
  • Fluid:基于 Hexo 的一款 Material Design 风格的主题,Hexo 默认的主题比较朴素。
  • GitHub:在线软件源代码托管服务平台。建立远程仓库,使用 Git 关联 GitHub,将本地仓库管理的数据推送到远程仓库。
  • GitHub Pages:GitHub 提供的静态网站托管服务,托管固定的 GitHub 仓库:<username>.github.io

【脑海整理中……】

【注】:文字说明远比简单地给出做法重要,虽然后者更实在。遗憾的是,本篇博文是残稿,缺少广角说明。

【注】:本篇博文稍微有点价值的是“文件管理和附属资源显示”章节。该章节讲解了文档和博文同时显示本地图片的思路和处理方案,简浅但明晰。若嫌麻烦,直接看“文档和博文同时显示本地图片”小节。

【注】:Github Pages 的说明请看前篇,或者看官方文档。

【注】:本篇博文讲解基于“Hexo - Git - Github Pages 仓库(public)”架构建立静态博客。用户是无法与静态 Web 网站进行交互的。

暂未参考,同质化,待删除:

(一)Github + Hexo 搭建个人博客超详细教程 - 知乎

如何快速搭建自己的博客平台 - 知乎

Hexo+GitHub Pages+服务器搭建个人网站 - 学思行录

Hexo教程,看这一篇就够了- How to系列-CSDN博客

1. 准备工作

Hexo 是一个快速、简洁且高效的博客框架,它能够解析 Markdown 格式的文档,渲染生成 HTML 文件。

Tip:Markdown 的使用较为简易,而 HTML、CSS 和 JavaScript 等编程语言的学习相对繁杂。当然,要想使网页更具个人色彩,还需对编程语言具有一定的了解。

Hexo 框架依赖于 Node.js 提供的运行环境和功能。npm(Node Package Manager)是 Node.js 默认安装和使用的包管理器,Hexo 可以使用 npm 或其他包管理器来安装和管理各种插件、主题和依赖包。

Tip:Node.js 是一个运行环境,它能够使 JavaScript 代码在服务器端运行。一般地,用户只需使用其包管理器,而无需系统学习其知识。

Git 是版本控制系统。通过它,用户可以很方便地管理本地博客数据,并将本地博客部署到 Github Pages 仓库。

1.1 安装 Git

Git 详细安装教程(详解 Git 安装过程的每一个步骤)_git安装-CSDN博客

如果 C 盘空间充足,默认安装即可。只需配置 Git 用户名和邮箱,以便区分不同提交者的身份。

Git Bash 配置 Git 用户名和邮箱:

1
2
git config --global user.name "your username"
git config --global user.email "your email address"

1.2 安装 Node.js

如果 C 盘空间充足,默认安装即可。只需修改 registry 和配置环境变量。

1.2.1 安装

Node.js官网 下载与操作系统所匹配的最新的 .msi 长期稳定版,然后按步骤安装。

默认的安装路径在 C:\Program Files 目录下。因 C 盘空间不足,将其修改为 E:\APP 目录下。

安装完后,msi 格式的安装包会自动将【Node 安装目录】添加到 Path 环境变量中,而 Node 程序(node.exe)和 npm 程序(npm.cmd)在 Node 安装目录下,因此 CLI 能够在任意路径下执行两者程序。

查看环境变量进行验证:【个人电脑】右键 →【属性】→【高级系统设置】→【高级-环境变量】→【系统变量-Path】,发现已配置 E:\APP\nodejs\

CLI,全称 Command-line interface,译为命令行界面。Windows 系统可使用 cmd.exe 或 PowerShell,推荐使用 Git Bash。

CLI 执行命令 node -vnpm -v,若显示对应版本号,则说明安装成功。

1.2.2 修改全局模块安装目录和缓存目录

npm 的全局模块安装目录和缓存目录默认都在 C 盘下。

执行如下命令进行查看:

1
2
3
4
# 查看npm的全局模块安装目录。默认:C:\Users\用户\AppData\Roaming\npm
npm get prefix
# 查看npm的缓存目录。默认:C:\Users\用户\AppData\Local\npm-cache
npm get cache

因 C 盘空间不足,将两者改到 Node.js 的自定义安装目录下(E:\APP\nodejs\)。

先在该目录下新建 “node_global” 和 “node_cache” 两个文件夹,然后执行如下命令进行修改:

1
2
3
4
# 设置 npm 的全局模块安装目录为 "node_global" 文件夹。全局安装到 node_global\node_modules\ 目录下。
npm config set prefix "E:\APP\nodejs\node_global"
# 设置 npm 的缓存目录为 "node_cache" 文件夹。
npm config set cache "E:\APP\nodejs\node_cache"

1.2.3 配置环境变量

【个人电脑】右键 →【属性】→【高级系统设置】→【高级-环境变量】→【系统变量】

  1. 全局安装的模块的程序就在 “node_global” 路径下,将 “node_global” 路径添加到 Path 变量中(E:\APP\nodejs\node_global),方便 CLI 在任意路径下执行 node 全局模块的命令。
  2. 很多博文新建变量,变量名为 NODE_PATH,变量值为全局 node_modules 的路径。该变量用于扩展 Node.js 的模块查找路径(默认在项目的本地 node_modules 目录查找)。通常不建议手动设置,因为可能导致依赖混乱和版本冲突。(搭建静态博客没必要新建该变量。)

Tips:

  • 系统变量作用于所有用户和程序,而用户变量只影响当前登录的用户。对于个人计算机,通常只有一个用户,两者的实际差异很小。在日常使用中,修改用户变量已足够满足大部分需求。
  • 在 Windows 系统中, 在 Path 变量中的路径可以省略最后的反斜杠(\),不会影响系统识别。

NODE_PATH 变量的说明:

  • 除非你有特殊需求,否则不推荐常规使用。比如:在某些开发或测试环境中,需要全局模块访问,避免重复安装公共依赖。
  • 现代 Node.js 开发推荐通过局部 node_modules 或使用包管理工具(如 npmyarn)管理依赖,而不是依赖 NODE_PATH
  • 兼容性问题:不同环境和不同Node版本下,NODE_PATH的行为可能略有差异。

1.2.4 registry(源仓库)

粗览,可删:npm 和 cnpm 的区别,你真的搞懂了嘛 - 爱看星星的稻草人 - 博客园

npm 安装模块是从源仓库下载对应的包。通过命令 npm config get registry 查看当前源仓库的地址,默认为 http://registry.npmjs.org 。因为 npm 默认源仓库的服务器在国外,在国内使用 npm 安装模块时,经常会出现下载缓慢或模块安装失败等问题。有两种方式解决该问题,如下所示:

  1. npm 的源仓库改为使用阿里维护的淘宝镜像地址
1
2
# 修改 npm 的源仓库地址为阿里维护的淘宝镜像地址:https://registry.npmmirror.com
npm config set registry https://registry.npmmirror.com
  1. 使用 cnpm 代替 npm,install 模块
1
2
# npm 安装 cnpm 插件到全局模块安装目录,并设置 cnpm 的源仓库地址为国内的淘宝镜像地址
npm install -g cnpm --registry=https://registry.npmmirror.com

npm 是 node 官方的包管理器,cnpm(gzip 压缩支持)是淘宝定制的中国版 npm 插件。安装模块时可使用 cnpm 来代替 npm,两者的下载命令基本一致。

npm 命令安装模块:

  1. npm install -g package-name:全局(-g or --global)安装指定包。
  2. npm install package-name:本地安装指定包。

cnpm 命令安装模块时,cnpm 替换 npm 即可。

1.2.5 权限修改与下载测试

  1. 确保当前用户对全局模块安装目录具有读写权限,否则使用 npm 全局安装包时可能会遇到权限不足的错误。

Tip:修改用户组权限,而不是“以管理员身份运行”程序。可参考:Windows用户组与权限

【node_global】→【属性】→【安全】→【Authenticated Users】→【编辑】→勾选【写入】

  1. 确保当前用户对缓存目录具有读写权限,否则可能会影响缓存的使用和更新。(操作同上)

CLI 执行命令 npm install express -g,下载 express 模块到全局模块安装目录。

1.2.6 版本升级

如何更新NodeJs到最新版本? - 掘金

适用于 Windows 和 macOS 的通用方式:官网下载最新 LTS 版本,然后重新安装在原安装路径下。 这样更新无需重新配置环境变量。

操作步骤如下:

  1. 执行命令 node -v,查看当前版本是否为最新版。
  2. 执行命令 where node,查看之前的安装路径。
  3. Node.js官网 下载与操作系统所匹配的最新的 .msi 长期稳定版,然后按步骤安装在原安装路径下。
  4. 最后测试是否安装成功:执行命令 node -v ,打印版本信息。

1.3 安装 Hexo

npm 安装 Hexo 模块到全局模块安装目录:

1
npm install -g hexo-cli

1.4 注册 GitHub 账号

GitHub官网 注册账号。

2. 本地博客初体验

本地博客是指 Hexo 本地项目;使用 Hexo 初始化文件夹,以之作为本地博客项目。

2.1 建立本地博客

任选位置新建文件夹,本人选择 E:\ningc5-blog\blogRoot\ 文件夹。其中:E:\ningc5-blog\ 目录用于存放与博客相关的内容;blogRoot\ 是专门的本地博客项目目录,简称为站点根目录

在站点根目录下执行以下命令:

1
2
hexo init		# Git clone hexo-starter 和 hexo-theme-landscape 主题,包管理器下载依赖。
npm install # 比对依赖项配置文件,然后更新依赖(如果需要)。

执行完后,本地博客项目初始化完成。

hexo init 命令的具体作用:int 命令 | Hexo

npm install 命令的作用:深入理解 package.json 文件与 package-lock.json 文件-CSDN博客

此时,站点根目录下存在一系列文件,如下图所示:


在站点根目录下执行以下命令:

1
2
hexo g		# 生成博客。【hexo generate】
hexo s # 启动服务器。默认情况下,访问地址为:http://localhost:4000/。【hexo server】

执行 hexo g 命令

执行 hexo s 命令


浏览器键入 http://localhost:4000/ ,若出现如下界面,则本地博客建立成功。本地预览完后,命令行【Ctrl + c】关闭服务器,避免 4000 端口被一直占用。

本地博客默认首页

2.2 关于博客项目文件夹的说明

Hexo文件结构 - 简书

暂未遇到的问题:hexo博客文件夹下删除了db.json之后,之前的分类(categories)还在? - 知乎

  • node_modules/:博客项目的模块安装目录。

  • themes/:主题文件夹。Hexo 会根据主题来生成静态页面。

  • _config.landscape.yml:默认主题的配置文件。默认主题包在 node_modules/ 目录下。

  • package.json 和 package-lock.json:博客项目的依赖项配置文件。

  • _config.yml:网站的配置文件。

  • scaffolds/:模版文件夹。new 命令新建文章时,Hexo 会根据 scaffold 来创建文件。

  • source/:资源文件夹;用于存放用户资源,比如 Markdown 文档、静态资源等。

    1. source/_posts/:专门用于存放博文(html)的原始文档(md)。
    2. source/images/:自建的图片文件夹。
  • public/:generate 命令的输出目录,一般不直接操作里面的文件。静态站点的位置,相当于“博客网站根目录”,访问博客就是访问 public 目录下的资源文件。

执行 generate 命令时:Hexo 会解析资源文件夹下的 Markdown 和 HTML 文件(以 _开头命名的文件/文件夹和隐藏的文件将会被忽略 ,不包括 _posts 文件夹),渲染得到的 html 文件会输出到 public 文件夹,此外还会在站点根目录下生成一份缓存文件(db.json);而其他文件会被直接拷贝到 public 文件夹(不包括以 _开头命名的文件/文件夹和隐藏的文件)。

Tip:执行 generate 命令时,Hexo 渲染的主要目标就是 source/_posts/ 目录下的 md 文件,生成的 html 文件就是所说的博文。

explain:上节浏览器所展示的 hello-world 博文的原始 md 文档是执行 hexo init 命令时下载的。执行 generate 命令时,/source/_posts/hello-world.md 文档被渲染成 hello-world.html 文件并输出到 public/ 目录下。

3. 网络博客

网络博客,即能够在因特网上浏览的个人博客网站。

3.1 GitHub Pages

按官方文档操作即可。

创建 GitHub Pages 站点 - GitHub 文档 ,public GitHub Pages 仓库

配置 GitHub Pages 站点的发布源 - GitHub 文档

3.2 Git 部署博客到 GitHub Pages

一键部署 | Hexo

标题:基于 hexo-deployer-git 部署

Hexo 提供快速、简便的部署策略。在安装 与服务器/存储库提供的部署方法兼容的必要插件 的情况下,进行相关配置后,只需要一条命令(hexo deploy)即可将网站部署到服务器上。

使用 Git 将本地博客部署到 GitHub Pages,直白地说,就是将 public/ 目录下的所有文件,而不是 public/ 目录,push 到 GitHub Pages 仓库。

Tip:hexo deploy 命令的具体作用——先将静态站点(public/)的内容复制到 .deploy_git/ 目录下,然后在 .deploy_git/ 目录下执行 Git 命令(init、add、commit、push)。

  1. 安装 hexo-deployer-git 插件
1
npm install hexo-deployer-git --save
  1. 编辑 _config.yml
1
2
3
4
5
6
7
deploy:
# 类型。
type: git # 采用git部署。
# 仓库连接方式,可以是【HTTPS+密码】、【HTTPS+token】或【SSH】。
repo: https://github.com/NingC5/NingC5.github.io.git # 采用【HTTPS+密码】,HTTPS见下图。
# 分支名称,与 GitHub Pages 仓库的默认分支名一致。
branch: main

  1. 部署

Git Bash 执行 hexo d 命令实现部署。因为 Git 连接仓库采用【HTTPS+密码】的方式,第一次连接要求输入用户名和密码进行身份验证(浏览器会自动跳转出认证页面)。

  1. 验证

浏览器键入 https://<username>.github.io 查看个人博客网站。

4. 选择主题

Hexo 的默认主题(landscape)比较朴素,官网提供了丰富的 主题样式,常用有 Next、Butterfly、Fluid 等。可以查看不同主题的 Demo,自行做出选择。不同主题的差异主要在生态建设及插件集成,外在表现是页面布局。

16 款精美的hexo 博客主题推荐 - 鹏叔的技术博客

笔者选择 Fluid 主题,仅仅是因为其博文页右侧的目录设计。

Tip:如果不满足于主题的默认页面布局和样式,可以修改源代码,形成自己的页面风格。

4.1 Fluid 主题

  1. 在站点根目录下执行 npm install --save hexo-theme-fluid 命令来下载 Fluid 主题包。

  2. 移动 fluid 主题文件夹并改名:node_modules/hexo-theme-fluidthemes/fluid。(本人移动并改名只是为了方便找到它。后期可能想换主题?)

  3. _config.yml 配置文件中指定主题和语言:

    1
    2
    theme: fluid  		# 指定主题为 Fluid。默认主题是 landscape。
    language: zh-CN # 指定语言为中文。
  4. 执行 hexo ghexo s 命令后,浏览器键入 http://localhost:4000/ ,查看 Fluid 主题效果。

fluid 主题的默认格式界面

4.2 配置文件

配置:使用代替主题配置文件 | Hexo

hexo 支持多配置文件合并覆盖生效;配置文件的优先级从高到低:_config.yml_config.[theme].yml、主题目录下的_config.yml。主题更新后,主题目录下的 _config.yml 会被替换。

强烈建议】:将所有的主题配置集中在独立的 _config.[theme].yml 配置文件中,以方便管理。

在站点根目录下创建 _config.fluid.yml,然后复制 Fluid 主题配置文件(fluid/_config.yml)的内容。

注意】:配置项的 key 和 value 之间用 英文冒号+空格 连接。 否则清理或部署时会报错:can not read a block mapping entry。当然,也可能是报错点之前存在格式错误。

5. 博客撰写

在站点根目录下执行 hexo new [layout] <title> 命令来创建一篇新文章或新页面。

5.1 布局

1
2
# _config.yml
default_layout: post # 默认值。

layout 是布局(版面)。Hexo 共有三种 layout:postpagedraft。 每种布局创建的文件会被保存到不同的路径。

布局 路径
post(文章) source/_posts/
page(页面) source/
draft(草稿) source/_drafts/

使用 new 命令来新建时,如果 layout 缺省,则默认使用 _config.yml 配置文件中的 default_layout 参数代替,默认值为 post。

  1. 若 layout 为 post,则会在 source/_posts/ 目录下生成一篇文章——博文(html)的原始文档(md)。
  2. 若 layout 为 page,则会生成 source/title/index.md
  3. 若 layout 为 draft,则会在 source/_draft/ 目录下生成一篇草稿。

5.2 文件名称(title 部分)

1
2
# _config.yml
new_post_name: :title.md # 默认值。:title 是占位符,值为 <title> 参数值。
  1. 使用 new 命令来新建文章或草稿时,默认使用 title 作为文件名(前缀部分)。如果 title 包含空格,请使用引号括起来。 如果 title 包含 ./ 等符号,会转换成 - 连接。
  2. 使用 new 命令来创建页面时,Hexo 会创建一个以标题为名字的目录,并在目录下放置一个 index.md 文件。

如果要更改默认文件名,可以更改 new_post_name 配置项的值。例如, :year-:month-:day-:title.md 将在文件名前加上创建日期。(没必要,在“文件管理与附属资源显示:文件管理(下)”小节会提到)

5.3 草稿

Hexo 默认不会渲染 source/_draft/目录下草稿 md 文档。可使用 hexo publish draft <filename> 命令发表草稿,即将草稿移到到 source/_posts/ 目录下。

当然,也可以在运行 generate 命令时,添加 --draft 选项,或在配置文件中启用 render_draft 设置,来渲染草稿。(别搞这个操作)

5.4 模板 & Front-matter

文章的front-matter使用详解 | Wang-YH

使用 new 命令来新建时,Hexo 会根据 scaffolds 文件夹内相对应的模板文件来建立文件。一般只需要修改文章或草稿的模板文件。

例如,执行 hexo new post "test" 命令时,Hexo 会根据 scaffolds/post.md 模板文件的内容建立 md 文档。如下所示:

源代码模式查看

md 文档开头的代码块就是 Front-matter。

5.4.1 Front-matter

Front-matter(前页|前置内容)是文档开头的 YAML 或 JSON 代码块,用于配置文档的各种属性(元信息)。 以 YAML 格式书写时,Front-matter 以三个破折号结束;以 JSON 格式书写时,Front-matter 以三个分号结束。

YAML front matter ——在 Obsidian 笔记中加入属性 - 知乎

Front-matter 常用的设置有:title、date、categories、tags、excerpt、permalink。

  1. title

title 是文章的标题,默认为 <title>(模板中的默认设置)。

  1. categories & tags(分类 & 标签)

只有文章支持分类和标签。 分类按顺序应用于文章,从而形成分类和子分类的层次结构。 标签是在相同的层次结构上定义的,因此它们的出现顺序不重要。

1
2
3
4
5
6
categories:
- Programming
- Java
tags:
- 编程
- IO

如果想应用多个分类层次结构,请使用一个名称列表而不是一个单个名称。 Hexo 会将每个分类视为独立层次结构。

1
2
3
4
5
categories:
- Programming
- Java
- [编程, 博客搭建]
tags: [编程, IO]

  1. excerpt(摘要)

摘要会出现在博客首页,用于对博文进行必要的简介。

方式一:在文档正文使用 <!-- more --> 截断,之前的文字将会被视为摘要。此方式的摘要会出现在博文中。

方式二:在 Front-matter 中指定 excerpt: 值。此方式的摘要不会出现在博文中。

本人按需采用了方式二。本人习惯在文档开头编写文档概述,若摘要内容出现在博文开头显得不美观。

  1. permalink(永久链接)

覆盖文章的永久链接(覆盖配置文件中的该配置)。永久链接应该以 /.html 结尾。

5.4.2 文章模板

修改文章模板文件:scaffolds/post.md

1
2
3
4
5
6
7
8
---
title: {{ title }} # 读取 new命令的title参数值 作为文章主题
excerpt: # 摘要
author: shaton沙桐 # custom auther's name
date: {{ date }} # 读取 new命令的执行时间 作为文章date
categories: # 自定义层级目录
tags: # 自定义标签
---

按需删改。

【注意】:如果文档 Front-matter 部分的属性无值,则删除该属性。否则执行 generate 命令时,Hexo 可能会报错: ValidationError: ‘null’ is not a string! 。这是属性缺失造成的。

5.6 永久链接

permalink 是文章的永久链接。可以在配置文件(config.yml)中统一设置所有博文的永久链接格式。或者在每篇文档的 Front-matter 部分单独设置每篇博文的永久链接。

1
2
3
4
5
6
7
8
# _config.yml
permalink: :year/:month/:day/:title/ # 默认值。

# permalink 推荐以 `/` 或 `.html` 结尾。
# permalink: posts/:title/ # 推荐。占位符":title"是相对于"source/_posts/"文件夹的文件名称
# permalink: posts/:name/ # 推荐。占位符":name"仅是文件名称。
# permalink: posts/:title.html # 推荐
# permalink: posts/:name.html # 推荐

永久链接(Permalinks) | Hexo 有占位符的描述说明。

注意!对 permalink 而言,占位符 :title 是相对于 “source/_posts/“ 文件夹的文件名称。 例如,source/_posts/test/test3.md 文档的 :title 对 permalink 而言为 test/test3

此外,【permalink结构】还与 generate 命令的输出目录有关。(在”public/ 目录下图片的真实路径“章节讲解)

6. 工作流与命令(待改)

Hexo-常用命令详解 | 个人博客

操作流程如下:

  1. 首先,创建 md 文档并编写内容。一般使用【new 命令】创建 md 文档,此文档带有模板设置的一些 Front-matter 内容,然后补充 Front-matter 部分。当然也可以直接创建 md 文档,但是需要从头到尾设置 Front-matter。
  2. 文档编写完后,使用【generate 命令】生成博客。
  3. 接着,使用【server 命令】启动服务器。在本地预览博客:http://localhost:4000/ 。如果本地预览没问题,【ctrl + c】关闭服务器,避免端口被一直占用。
  4. 然后,使用【deploy 命令】部署到远程仓库。浏览网络博客:https://ningc5.github.io/
  5. 如果博文需要修改,则修改 md 文档内容;然后,使用【clean 命令】清楚缓存文件和 public/ 文件夹;接着,继续执行【步骤2】、【步骤3】和【步骤4】。
  6. 如果博文需要删除,则删除 source/_posts/ 目录下的 md 文档及其文章资源文件夹;接着,继续执行【步骤2】、【步骤3】和【步骤4】。

Hexo 如何删除已经发布的文章 | 竹山一叶

?若使用 Github Actions 自动部署,只需要删除 md 文档,然后 push 即可。

【clean 命令】:该命令的执行是必要的。如果修改 md 文档的内容而不执行该命令,Hexo 并不会重新渲染 md 文档,这意味者博文还是旧内容。如果删除 md 文档而不执行该命令,Hexo 并不会删除 public/ 目录下的博文,这意味着博客中仍然存在需要被删除的博文。

【server 命令】:如果嫌麻烦,可以跳过该命令。不过,本地预览能够立即浏览到博客的变化,而网络博客需要等待。此外,如果文档仅更改文字,博文的变化也能在本地预览实时跟进。

7. 文件管理与附属资源显示

使用 hexo new post <title> 命令时,Hexo 会在 source/_posts/ 目录下创建一篇文章,具体地说是一份 md 文档,它就是博文的原始文件。该文档除了文字信息外,还可以包含图片(主要)、gif、视频等附属资源。这些文件需要组织化管理,以避免数量过多而混乱。

Hexo 提供了 post_asset_folder 选项以启用文章资源文件夹,这解决了部分文件管理的问题。当然,这些文件的目录结构除了在 source/_posts/ 目录下可以被设计,在 public/ 目录下也能被设置。

附属资源显示是指 md 文档和博客页面同时显示附属资源(比如图片、gif、视频等)。当然,博客页面本身也是一种资源文件(html)。public/ 目录是静态站点的位置,相当于“博客网站根目录”(类似于 Tomcat 类路径)。访问博客页面就是访问 public/ 目录下的 html 文件。博客页面能够显示意味着地址与 html 文件的路径是一致的。Hexo 的默认处理即可使博客页面显示,我们关注的焦点是博客页面中附属资源的显示。 若附属资源在博客页面中能够显示,这意味着【html 文件中附属资源的引用路径】与【public/ 目录下附属资源的真实路径】是一致的,而这两者都与 generate 命令的执行有关。

文件管理和附属资源显示是前后呼应的。本章 ”附属资源显示“ 以 ”本地“ ”图片“ 为例,其他附属资源或远程资源同理。

7.1 文件管理(上)

未采用,但链接及其引用链接可参考:Hexo 文章管理:子文件夹管理 + 保留文章永久链接 - Muxiner’s Blog

文件主要指博文在 source/_posts/ 目录下的原始 md 文档及其附属资源文件。此外,还有部分博客资源文件。

  1. 一般地,在 md 文档中使用 md 语法 ![](imageLocation) 和相对路径引用本地图片,这样处理也方便本地迁移。md 文档附属资源所在的文件夹称为文章资源文件夹
  2. 至于博客资源文件(比如全局图片、CSS、JS 文件等),放在【source/ 目录下任意一个非 _ 开头的文件夹】中即可,该文件夹被称为全局资源文件夹
1
2
3
4
5
6
7
8
9
10
11
blogRoot
├── source
│ ├── _posts
│ │ ├── filename【文章资源文件夹】
│ │ │ └── 图片.jpg【文章引用的图片】
│ │ └── filename.md【文章,该文章引用”图片.jpg“的语法:![](filename/图片.jpg)】
│ ├── images【全局资源文件夹:图片】
│ | ├── 背景图.jpg
| | └── 小图标.ico
| ├── css【全局资源文件夹:css】
| └── js【全局资源文件夹:js】

可以通过将配置文件(config.yml)中的 post_asset_folder 选项设为 true 来启用文章资源文件夹。

1
2
# _config.yml
post_asset_folder: true # 启用文章资源文件夹

启用后,使用 new 命令创建文章时,Hexo 就会自动创建一个和文章同名的文章资源文件夹(作用一)。

7.2 Typora 偏好设置

在 Typora 中使用图片 | TyporaChina

Typora嵌入视频和PDF - 知乎

Typora使用技巧之插入图片及图片上传 - 知乎

Typora 是常用的 Markdown 语法编辑器,它支持实时预览。

常使用 md 语法 ![](src) 插入图片。当 src 是 URL 时,引用远程库图片;当 src 为绝对/相对路径时,引用本地图片。 一般地,采用 md 语法和相对路径引用本地图片,以方便管理和迁移。 当然,Typora 也支持 <img> 标签(html 语法)显示图片:<img src="imageLocation"/> 。缩放图片时,md 语法就会转换成 html 语法。

Typora 还支持拖放图片和从剪贴板上粘贴图片。当使用这两种方式插入图片时,Typora 可以设置插入图片时的动作。请进行如下设置,以方便管理:

  1. 【文件 - 偏好设置】→ 【图像】→ 【插入图片时…】→ 【复制到指定路径:./${filename}
  2. 勾选【优先使用相对路径】

Tip:为了与 hexo 适配,Typora 设置插入图片时复制到指定路径 【./${filename}】,而不是它默认提供的选项:【复制图片到 ./${filename}.assets 文件夹】。

设置完后,拖放图片或从剪贴板上粘贴图片时,Typora 会进行如下操作:

  1. 在文档所在目录下创建与文档同名的文件夹 filename/,并将要插入的图片复制到该文件夹中。
  2. 插入图片,采用相对路径:![](filename/imageFullName)

7.3 文件管理(下)

当文章越来越多时,文章及文章资源文件夹需要进一步划分目录结构,以方便查找。

这节给出两种处理方式。

  1. 按年月划分

配置项 new_post_name 不仅与文件名称相关,还涉及文档的目录结构。

例如,将该配置项设置为:year/:month/:title.md 时,使用 new 命令新建文档会按年月划分。

示例:执行 hexo new post "test2" 命令时,Hexo 会生成 source/_posts/2025/4/test2.md

  1. 按文章类别划分

根据文章的内容确定文章类别来划分文章及其资源文件夹所属的目录结构。

使用 new 命令时添加 --path 选项,自定义文档的路径。

示例:执行 hexo new post -p test/test3 "测试文档3" 命令时,Hexo 会生成 source/_posts/test/test3.md

注意!path 部分的最后必须是文件名(可以是前缀名,会自动添加 new_post_name 设置的后缀;也可以是带后缀的全名)!后面的 title 也必须指定!否则可能会产生非期望的结果! 示例的文件名为 test3,title 为 测试文档3,此 title 会作为博文的标题(Front-matter 部分的 title)。

Tip:使用 new 命令和 path 选项需要知晓它的执行结果。当然,也可以直接通过手动创建目录结构和文档的方式来达到同样的效果。


当博文产出不多时,可采用按年月划分。但私以为该结构比较死板。本人习惯按文章类别划分。

当博客需要 多语种支持 时,也可以修改该 new_post_name 配置项。

7.4 public/ 目录下图片的真实路径

1
2
3
4
5
6
7
8
9
10
11
blogRoot
├── source
│ ├── _posts
│ │ ├── filename【文章资源文件夹】
│ │ │ └── 图片.jpg【文章引用的图片】
│ │ └── filename.md【文章,该文章引用”1.jpg“的语法:![](filename/图片.jpg)】
│ ├── images【全局资源文件夹:图片】
│ │ ├── 背景图.jpg
| │ └── 小图标.ico
| ├── css【全局资源文件夹:css】
| └── js【全局资源文件夹:js】

执行 generate 命令时,Hexo 的默认行为:

  1. 渲染 source/ 目录下的 Markdown 和 HTML 文件(以 _开头命名的文件/文件夹和隐藏的文件将会被忽略 ,不包括 _posts 文件夹),并将渲染得到的 HTML 文件会输出到 public/ 目录下。
  2. 在站点根目录下生成一份缓存文件(db.json)。
  3. 将其他文件直接拷贝到 public/ 目录下(不包括以 _开头命名的文件/文件夹和隐藏的文件)。

全局资源文件夹拷贝到 public/ 目录下。

1
2
3
4
5
6
7
blogRoot
├── public
│ ├── images【全局资源文件夹:图片】
│ | ├── 背景图.jpg
| │ └── 小图标.ico
| ├── css【全局资源文件夹:css】
| └── js【全局资源文件夹:js】

而【md 文档渲染后的 HTML 文件】以及【文章资源文件夹中的附属资源文件】按照【permalink 结构】输出到 public/ 目录下。

输出 html 博文到 public/ 目录下是 Hexo 的默认行为; 而输出【文章资源文件夹中的附属资源文件】是启用文章资源文件夹(post_asset_folder 选项设为 true)的结果(作用二)。 Hexo 复制无法渲染的文件默认是忽略 _posts/ 文件夹的。

Tip:文章资源文件夹必须与文章同名,否则 Hexo 也不会复制资源文件,这就是前文 Typora 设置插入图片时复制到指定路径 【./${filename}】的原因。文章资源文件夹是 Hexo 的一个功能模型,Hexo 读取数据时是按文章名称获取文章资源文件夹的。

permalink 结构】示例:

  1. permalink: posts/:name/ ,该 permalink 结构为 posts/文章名称/ ,【html 博文】及其【文章资源文件】都在 public/posts/文章名称/ 目录下。
1
2
3
4
5
6
blogRoot
├── public
│ └── posts
│ └── filename
│ ├── index.html【html博文】
│ └── 图片.jpg
  1. permalink: posts/:name.html ,该 permalink 结构为 posts/ ,【html 博文】及其【文章资源文件夹】都在 public/posts/ 目录下。
1
2
3
4
5
6
blogRoot
├── public
│ └── posts
│ ├── filename.html【html博文】(两种结尾方式,html文件名不一致,文件结构不一致)
│ └── filename
│ └── 图片.jpg

7.5 html 文件中图片的引用路径

博客全局设置,比如 Fluid 主题的浏览器标签的图标,在配置文件中这样设置:favicon: /img/fluid.png 。博客页面图标的链接为 http://ip:端口号/img/fluid.png ,获取的就是 public/img/fluid.png 资源。如果需要替换,可以将自定义图标文件(小图标.ico)放到全局资源文件夹(source/images/)中,然后修改该配置项:favicon: /images/小图标.ico


md 文档显示本地图片采用的 md 语法和相对路径。执行 generate 命令时,hexo-renderer-marked 插件(Hexo 默认的 Markdown 渲染器)将 md 文档渲染成 html 文件(博文),图片的引用格式会发生相应变化。

  1. md 语法转换成 <img> 标签(html 语法)
  2. 路径【relative path】(md)被渲染成 【/relative path】(html)

例如,![](test/girl.jpg)<img src="/test/girl.jpg" >

marked 对相对路径默认处理方式是——prepend root 值到路径内部。因为 marked.prependRoot 默认值为 true,而 root 默认值为 /

详情见 node_modules/hexo-renderer-marked/lib/renderer.jsnode_modules\hexo-util\dist\url_for.js 等程序源代码。可参考:Hexo框架renderer源代码的部分注释

marked 渲染问题】:需要强调的是,如果 md 语法引用本地图片的相对路径存在空格,比如 ![](test/背 景.jpg)![](te st/背景.jpg) ,marked 不会进行转换,而是按字符串输出。

7.6 过滤器与路径转换插件

Hexo 官方提供了 过滤器(Filter) | Hexo 钩子,允许开发者在不修改 Hexo 源码的前提下,对渲染过程进行干预。

  1. before_post_render 在文章渲染前执行,例如 hexo-asset-img 插件。
  2. after_post_render 在文章渲染完成后执行,例如 hexo-asset-image 插件。

hexo-asset-image 插件在文章渲染完成后再次处理路径。该插件已被作者归档,现在无法适配新版本 Hexo。

私改 hexo-asset-image 插件来兼容 Hexo 新版本:hexo-asset-image在hexo6.3.0下的使用以及与abbrlink插件的修改-CSDN博客

hexo-asset-img 插件在文章渲染前先处理路径。它在文章渲染前将本地图片相对路径转换 asset_img 标签。asset_img 标签是 Hexo 3 支持的新特性。

Tip:asset_img 标签见 7.8 章。

7.7 文档和博文同时显示本地图片

Hexo的工作原理探究 | Java技术经验分享

采用 hexo-asset-image 插件,过时,但文章结构不错:Hexo 中完美插入本地图片 | JK Notes

虽有思路,也忽略:Hexo 引用本地图片以及引用本地任意位置图片的一点思路 | 养恐龙

【思路有参考价值】:渲染 md 文档前,截取图片相对路径(filename/1.jpg)为图片名(1.jpg),以适配官方文档给出的糟糕的处理方案(使用-Markdown-嵌入图片);该博文的结构也参照官方文档:Hexo中插入图片的方法 - Hazel

私改 marked 插件的 renderer 程序源代码,funny(文档说明是错误的,结果是正确的):Xu-pixel/hexo-renderer-marked: Markdown renderer for Hexo

使用图床部分待参考?:hexo使用Hexo-asset-image图片无法正常显示的一些解决方案 | CodeCook

文档显示本地图片通常使用 md 语法和相对路径,而博文显示本地图片要求【html 文件中图片的引用路径】与【public/ 目录下图片的真实路径】一致。诸如 hexo-asset-imagehexo-asset-img 等插件,会对图片的相对路径进行处理,以满足博文也显示本地图片的要求。

文档和博文同时显示本地图片的常用方案是使用图片路径转换插件。考虑到个人插件可能与新版本 Hexo 不适配的问题,在 Hexo 默认渲染机制的前提下,只修改 Hexo 配置也能使博文也显示图片。


方式一:使用 hexo-asset-img 插件。

hexo-asset-img | Hexo 本地图片插件: 转换 图片相对路径 为 asset_img


方式二:在 Hexo 默认渲染机制的前提下,只修改 Hexo 配置使得博文也显示图片。

只使用默认配置,则 generate 命令执行后,【html 文件中图片的相对路径】只会有两种情况:

  1. 相对路径不变(filename/图片.jpg),marked.prependRoot 选项设置为 false

文档采用 md 语法和相对路径引用本地图片时,文档和图片具有一定的层级结构(![](filename/图片.jpg))。考虑到【public/ 目录下图片的真实路径】是固定的【permalink结构】,若博文永久链接的路径缺失一层(permalink 值以非 / 结尾即可),则图片 URI 也能具有该结构(浏览器会自动将图片的相对路径与当前页面的路径进行拼接作为图片 URI)。这样图片 URI 就与【public/ 目录下图片的真实路径】一致,博文也显示图片。

  1. 相对路径转换为绝对路径(/filename/图片.jpg),marked.prependRoot 选项采用默认值 true

当【public/目录下图片的真实路径】与转换后的绝对路径相同时,则博文也显示图片。只要 permalink=:name/permalink=:name.html,就能达到该要求;只是该 permalink 值会导致 public/ 目录下的博文的结构比较混乱(其实也无所谓)。

两种情况的设置:

  1. 相对路径不变(filename/图片.jpg),即 marked.prependRoot 选项设置为 false;则 permalink 值以 .html 结尾。
  2. 相对路径转换为绝对路径(/filename/图片.jpg),即 marked.prependRoot 选项采用默认值 true;则 permalink=:name/permalink=:name.html

示例:当 marked.prependRoot=falsepermalink=posts/:name.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
blogRoot   
├── source
│ └── _posts
│ ├── test
│ │ └── 1.jpg
│ └── test.md 【![](test/1.jpg)】

【执行 generate 命令】

blogRoot
├── public
│ └── posts
│ ├── test.html 【<img src="test/1.jpg">】
│ └── test
│ └── 1.jpg

博文 URL = http://ip:port/posts/test.html

图片 src = "test/1.jpg",浏览器会自动将图片的相对路径与当前页面的路径进行拼接作为图片 URL
"http://ip:port/posts/" 拼接 "test/1.jpg"
图片 URL = http://ip:port/posts/test/1.jpg

此时【图片 URI】与【public/ 目录下图片的真实路径】一致。

Tip:彩蛋在 shit 章节!有屑捞想给 marked 插件 pull request 吗?

7.8 内置标签

资源文件夹:相对路径引用的标签插件 | Hexo

标签插件:包含资源 | Hexo

Hexo 3 支持更多的内置标签在文章中引用其他资源,例如:

  1. {% asset_img slug [title] %}

其中,slug 是图片全名, [title] 是鼠标悬停提示。若 slug 包含空格,请使用英文引号("")括起来。

启动文章资源文件夹后,在文章中引用【文章资源文件夹中的图片】。 若采用此方式,博文能显示图片,而 md 文档中只是字符串。执行 generate 命令时,Hexo 会将其转换成路径正确的 <img> 标签。

示例:在 source/_posts/test/1.jgppermalink=posts/:title.html 的情况下,source/_posts/test.md 文档中的 {% asset_img "1.jpg" %}
被转换成 <img src="/posts/test/1.jpg">

  1. {% post_link filename [title] %}

其中,filename 是文档 Format-matter 部分的 title 值, 而不是文档名。请使用英文引号("")括起来。

示例:{% post_link "Hexo框架renderer源代码的部分注释" %}

本博文会显示该博文的链接:Hexo框架renderer源代码的部分注释

注意:slug 必须与文档名一致,否则 generate 命令执行出错。文档改名时会发生这种情况。

7.9 marked 新选项(shit)

使用-Markdown-嵌入图片 | Hexo

虽然官方文档提到,marked 3.1.0 引入了一个新选项,支持 md 文档使用 md 格式(![]() )嵌入图片而无需使用 asset_img 标签,使得文档和博文同时显示本地图片。

1
2
3
4
5
# _config.yml
post_asset_folder: true # 设置为 true,开启文章资源文件夹。
marked:
prependRoot: true # 默认值为 true
postAsset: true # 默认值为 false
  • 先不说这文档说明就是狗屎。
  • 其次,github 上 marked.postAsset 选项的说明与程序不符。
  • 再次,若启用新选项,md 文档中只有使用语法:![](1.jpg)(文档无法显示图片)时,博文才能显示图片。若 md 文档中使用语法:![](filename/1.jpg) ,则程序定位不到文章资源文件夹下的图片资源,导致图片的引用路径错误,博文无法显示图片。粗略地说,文档和博文,二者只能选其一显示图片。

【彩蛋】:至于为什么官方文档显得如此狗屎,是因为 renderer.js 源代码的错误。在源代码中,postPath 赋值出现逻辑错误,不应拼接文件前缀名。

修改 Hexo框架renderer源代码的部分注释 源代码:postPath = join(source_dir, dirname(postSource)); 。在文章资源文件夹开启的情况下,设置 prependRootpostAsset 为 true 即可。

8. 其他

8.1 困惑 & 处理

【marked 插件的渲染问题 | 错误】:文档中直接出现 hexo new [layout] <title> 字符串时,博文的后续内容、右侧目录栏和特效都失踪。

【marked 插件的渲染问题 | 错误】:若文档中直接出现 http(s) 链接地址,链接地址必须与后面的符号或字词空一格,否则链接地址渲染出错。

【marked 插件的渲染问题 | 美观】:md 文档使用 **内容** 格式加粗文字;当内容的顶端和尾部为符号时,若前后要与数字、字母或汉字连接,则必须空一格;否则博文显示不美观。

【marked 插件的渲染问题 | 错误】:当文档中采用内置标签时,若 slug 出错,执行 generate 命令会报错。因此不能随便改名。(不推荐使用内置标签 asset_link 引用本地博文。)

【marked 插件的渲染问题 |问题】:限制 Front-matter 部分的 title 属性值。& 符号及之后的值,不会被渲染为 HTML 元素的内容。

8.2 卸载插件

Hexo删除插件的命令与使用办法 | Hsyac

以卸载 hexo-asset-image 插件为例:

  1. 执行 npm uninstall hexo-asset-image 命令。
  2. 如果 node_modules/ 目录下仍有该插件包,删除。
  3. 如果配置文件、主题配置文件、package.jsonpackage-lock.json 仍有与该插件相关的配置信息,删除。

8.3 中英文空格

中英文之间空格能够让文章更美观, hexo-filter-auto-spacing 插件能够实现所有中英文之间自动空格。需要注意的是,该插件的作用范围是【所有中英文连接处】,可能不是很符合要求。 本人编写文档时,会在中英文数字等连接处手动添加空格,不是很需要该插件。


安装插件:

1
npm install hexo-filter-auto-spacing --save

_config.yml 文件中配置:

1
2
3
# hexo-filter-auto-spacing 插件,实现中英文之间自动加空格
auto_spacing:
enable: true

【困惑】:该插件卸载后再重新安装,无需配置,甚至设置为 false,仍然实现空格,这是 bug 吗?

【暂未遇到的问题】:hexo-filter-auto-spacing 插件会导致脚注插件不能正常运行。

附录(可略)

【注】:附录内容可能与主题无关,只是个人搜索!

  1. CLI

命令行相关概念梳理(CLI、Terminal、Shell、脚本) - 简书

到底什么是CLI? - 知乎

什么是CLI(命令行界面)、GUI(图形用户界面)、Terminal(终端)、Console(控制台)、Shell、TTY-CSDN博客

Github Pages托管静态博客-原理浅析 | ESON

使用Cloudflare为自定义域名的GithubPages实现HTTPS化 | Steffan’s Blog

github Page到底是干什么的?使用场景是什么?底层原理是什么?_github pages-CSDN博客

互联网、因特网和万维网傻傻分不清,一文带你彻底理解计算机中的各种网络-CSDN博客


Hexo+GitHubPages搭建静态博客
https://cornst.com/posts/Hexo&GitHubPages搭建静态博客.html
作者
shaton沙桐
发布于
2025年4月9日
更新于
2025年5月20日
许可协议