HEXO 开发笔记(1)主题
创建于 2024-12-28
更新于 2025-11-23
科技
hexo
theme

前言

年底终于闲了下来,考虑到 GitLab 自己的种种问题,前一阵把私有代码仓库迁移到了 Gitea,也顺势抽空系统化整理一下 Hexo 主题获取与自定义开发的流程,同时开发了自己的主题。本文作为“开发笔记”系列第一篇,聚焦于:

  1. Hexo 的基本功能与常用命令
  2. 如何检索、获取并配置第三方主题
  3. 自定义主题的目录结构、约定与最佳实践

撰写参考官方文档版本:Hexo 7.x(以实际使用为准)。

一、Hexo 基本功能与使用

1.1 核心概念与目录结构

Hexo 是基于 Node.js 的快速、简洁且高效的静态博客框架,核心职责:

  • 将 Markdown + Front Matter 转换为静态 HTML
  • 提供扩展体系:主题、插件(过滤器、标签、渲染器、部署器等)
  • 支持多种部署方式(Git、S3、FTP 等)

初始化后默认目录(关键子集):

code
1
2
3
4
5
6
7
8
9
. ├── _config.yml # 站点级配置(全局) ├── package.json # 依赖与脚本 ├── node_modules/ # NPM 依赖 ├── source/ # 原始内容(Markdown / 资源) │ ├── _posts/ # 正式文章 │ └── _drafts/ # 草稿(hexo new draft) ├── themes/ # 主题目录(可多主题并存) └── public/ # 构建输出目录(hexo generate 后生成)

补充:主题内部也有自己的 _config.yml(主题级配置),与根配置分离。

1.2 安装与初始化流程

全局配置 _config.yml 关键字段概览

_config.yml 是站点级主配置文件,常用核心段落:

分类 字段 说明
站点信息 title / subtitle / description / author 页面 <head> 与主题引用的基本元数据
URL url / root 部署后站点完整地址与根路径(影响生成链接)
语言与时区 language / timezone 语言包选择与日期渲染(如 zh-CN
目录结构 source_dir / public_dir / tag_dir / category_dir 源文件与构建输出及标签、分类页面目录名
写作 new_post_name / default_layout / post_asset_folder 新文章命名模板、默认布局、是否创建同名资源目录
永久链接 permalink / permalink_defaults 文章最终 URL 格式与默认占位符值
分页 per_page / pagination_dir 每页文章数与分页目录名
模板渲染 highlight / prismjs 代码高亮配置(二选其一或关闭)
主题 theme 当前使用主题名称
部署 deploy: 部署方式与仓库配置(如 type: git
服务器 port / logger 本地预览端口与日志级别

示例片段:

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
# 站点信息 title: My Blog subtitle: 分享与记录 description: Personal tech notes author: Tiger # URL url: https://example.com root: / # 写作与组织 new_post_name: :year/:month/:title post_asset_folder: true permalink: :year/:month/:day/:title/ permalink_defaults: lang: zh # 分页 per_page: 10 pagination_dir: page # 主题 theme: mytheme # 部署 deploy: type: git repo: git@example.com:/home/git/hexo.git branch: master

修改后需运行:hexo clean && hexo g 重新生效(某些字段如 theme 直接影响渲染)。

permalink 字段控制文章 URL 结构,不同模式对 SEO 有不同影响:

模式 示例 URL SEO 特性 适用场景
:year/:month/:day/:title/ /2025/11/23/hexo-theme/ ✅ 日期感强,利于时效性内容;URL 较长 新闻、日记类博客
:year/:month/:title/ /2025/11/hexo-theme/ ✅ 简洁且保留时间信息;URL 中等长度 推荐:技术博客、教程
:title/ /hexo-theme/ ✅ 最简洁,关键词权重高;无时间信息 产品文档、evergreen 内容
:category/:title/ /tech/hexo-theme/ ✅ 语义化强,利于站内结构;需维护分类 多主题站点
:id.html:abbrlink/ /12345.html/5a2b/ ⚠️ 无语义,对 SEO 不友好;URL 稳定 需避免中文转码或迁移保持链接

SEO 最佳实践建议

  1. 包含关键词:title 占位符确保 URL 中有文章主题(会自动转为 slug)
  2. 保持简短:避免过长 URL(< 75 字符为佳),:year/:month/:title/ 是平衡选择
  3. 使用连字符:Hexo 自动将空格转为 -,搜索引擎友好(优于下划线 _
  4. 避免中文直出:中文会被 URL 编码为 %E5%...,可用 hexo-abbrlink 或手动设置 Front Matter 的 slug 字段
  5. 一旦确定不轻易改:URL 变更会导致 404 和 SEO 权重丢失,需配合 301 重定向

示例配置(推荐用于技术博客):

yaml
1
2
3
4
5
6
7
# 简洁且有时间层级 permalink: :year/:month/:title/ permalink_defaults: lang: zh-CN # 或使用插件生成短 ID(需安装 hexo-abbrlink) # permalink: posts/:abbrlink/

自定义 slug 避免中文:

yaml
1
2
3
4
--- title: Hexo 主题开发指南 slug: hexo-theme-development-guide ---

最终 URL:/2025/11/hexo-theme-development-guide/

环境前置:Node.js (LTS)Git

bash
1
2
3
4
5
6
7
8
9
# 全局安装 Hexo CLI npm install -g hexo-cli # 初始化站点(当前目录为空时) hexo init blog cd blog # 安装依赖 npm install

1.3 常用命令速览

bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 创建新文章(正式) hexo new "文章标题" # 创建草稿 hexo new draft "草稿标题" # 本地启动预览(默认端口 4000) hexo server # 或 hexo s # 生成静态文件到 public/ hexo generate # 或 hexo g # 清理缓存与 public 输出 hexo clean # 生成并部署(需配置 deploy) hexo deploy # 或 hexo d # 组合:清理 + 生成 + 部署 hexo clean && hexo g && hexo d

1.4 Front Matter 要点

文章元信息写于文件首部 --- 包裹的 YAML 区域,用于:分类、标签、时间、永久链接、首页摘要截断控制。abbrlink 等字段通常由相关插件(如 hexo-abbrlink)自动生成,不建议手动填写。

示例:

yaml
1
2
3
4
5
6
7
8
9
10
11
--- title: 示例文章 date: 2025-11-23 10:00:00 updated: 2025-11-23 10:00:00 categories: - 科技 tags: - hexo - demo # abbrlink: (可选,由插件自动生成) ---

在正文“前言”后添加 <!--more--> 控制首页截断。

1.5 文章与资源组织策略

  • 使用 source/_posts/年/月/ 结构提升可维护性,可通过根 _config.ymlnew_post_name 自动生成层级,例如:
    yaml
    1
    new_post_name: :year/:month/:title
  • 启用资源跟随(推荐)在 _config.yml 设置:
    yaml
    1
    post_asset_folder: true
    然后新建文章后会自动生成同名资源目录(搭配 ![](/path) 或引用式链接)。
  • 图片放同名子目录:文章名/图片.png 并用引用式链接集中定义
  • 草稿先放 _drafts,确认后执行 hexo publish 草稿名 转正
  • scaffolds/ 目录可自定义新建文件的默认 Front Matter。例如修改 scaffolds/post.md
    markdown
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    --- title: {{ title }} date: {{ date }} categories: - 科技 tags: --- ## 前言 <!--more-->

二、主题获取与配置

2.0 根级与按主题配置文件说明

除了根 _config.ymlthemes/<theme>/_config.yml 外,可以在项目根使用 _config.<theme>.yml 为指定主题添加覆盖配置信息。最终合并优先级:

  1. _config.yml (基础全局配置)
  2. _config.<theme>.yml (当前主题的追加/覆盖层)
  3. themes/<theme>/_config.yml (主题自身默认)

这样可以在不改动主题源码的情况下定制导航、CDN、开关项。例如:

yaml
1
2
3
4
5
6
7
8
9
10
11
12
# _config.yml menu: home: / archives: /archives # _config.mytheme.yml (仅当 theme: mytheme 时生效) menu: tags: /tags categories: /categories cdn: enable: true js: https://cdn.example.com/js/

切换主题只需在 _config.ymltheme: mytheme 或运行临时命令:

bash
1
hexo s --theme mytheme

2.1 官方主题目录检索

访问 Hexo 官方主题目录 可以基于:星级、更新时间、关键字筛选。每个条目通常附:Demo、仓库地址、安装说明。

2.2 GitHub 搜索技巧

常用搜索关键字:hexo themehexo-theme-xxx。筛选策略:

维度 推荐标准
Stars > 100(视冷门领域而调整)
最近更新 < 6 个月更佳
Issue 回复 Maintainer 活跃,未长期无人处理
依赖 不滥用沉重前端框架(性能优先)

可用 GitHub 高级搜索:topic:hexo theme in:name,description pushed:>2025-05-01

2.3 安装与启用主题

三种常见方式:

bash
1
2
3
4
5
6
7
8
9
# 方式一:git clone cd themes git clone https://github.com/author/hexo-theme-example.git example # 方式二:作为子模块(便于上游同步) git submodule add https://github.com/author/hexo-theme-example.git themes/example # 方式三:npm(部分主题支持) npm install hexo-theme-example --save

在根 _config.yml 中设置:

yaml
1
theme: example

然后:

bash
1
hexo clean && hexo g && hexo s

2.4 常见主题配置项

主题级 _config.yml(位于 themes/<name>/_config.yml)常包含:

配置项 说明
menu 导航栏结构与顺序
favicon 站点图标路径
logo 主题 Logo(可选)
widgets 侧边栏组件控制
social 社交链接映射(GitHub/Email 等)
highlight 代码高亮方案(如 prism, highlight.js)
cdn 资源外链地址加速

修改后需要重新生成。

2.5 多主题切换与调试

Hexo 支持在根目录以 _config.<themeName>.yml 进行按主题的额外配置扩展,加载顺序为:

_config.yml_config.<当前 theme>.ymlthemes/<theme>/_config.yml

后者覆盖前者同名字段。

示例:

yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
# _config.yml site_name: My Blog menu: home: / archives: /archives # _config.example.yml (仅在 theme: example 时生效) menu: about: /about links: /links highlight: enable: true line_number: true

切换主题只需修改:

yaml
1
2
# _config.yml theme: example

或临时测试(不写入文件):

bash
1
hexo s --theme example

推荐保留多个主题目录进行对比:

bash
1
2
3
4
themes/ ├── example/ # 当前使用 ├── light/ # 准备测试 └── legacy/ # 历史版本

调试技巧:

  • 使用浏览器 DevTools 观察生成后的 DOM 结构 → 对应 layout/* 模板文件
  • 通过 hexo s --debug 查看渲染与路由日志
  • 避免直接修改第三方主题核心文件,可在自定义主题中复刻再改(便于升级)

三、自定义主题开发规范

3.1 主题目录基本结构

官方规范参考:Theme Guide。典型结构(模板文件可使用任意已安装渲染器支持的后缀,如 .ejs .pug .njk .swig):

code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
themes/my-theme/ ├── _config.yml # 主题配置 ├── layout/ # 页面模板(EJS / Pug / Nunjucks / Swig) │ ├── layout.pug # 通用外层布局(含 <head> / header / footer) │ ├── index.pug # 首页(文章列表) │ ├── post.pug # 单篇文章 │ ├── page.pug # 普通页面 │ └── _partial/ # 局部片段(导航、侧栏、meta 等) ├── source/ # 主题静态资源(会复制到 public) │ ├── css/ │ ├── js/ │ ├── images/ │ └── fonts/ ├── languages/ # 多语言 JSON / YAML(zh-CN.yml / en.yml) ├── scripts/ # 注册过滤器 / 标签 / 事件扩展(Node.js) └── package.json # 若主题需自身依赖

3.2 必备模板与渲染要点

模板文件后缀取决于已安装的渲染器插件(hexo-renderer-ejshexo-renderer-pughexo-renderer-nunjucks 等),以下示例分别展示 EJSPug

  • layout.*:所有页面的容器(含 head、SEO meta、全局样式与脚本)
  • index.*:文章列表循环

EJS 示例:

ejs
1
2
3
4
5
6
7
<% page.posts.each(post => { %> <article> <h2><a href="<%= url_for(post.path) %>"><%= post.title %></a></h2> <time><%= date(post.date, 'YYYY-MM-DD') %></time> </article> <% }) %> <%- partial('_partial/pagination', {page: page}) %>

Pug 示例:

pug
1
2
3
4
5
6
7
articleList each post in page.posts article h2 a(href=url_for(post.path))= post.title time= date(post.date, 'YYYY-MM-DD') != partial('_partial/pagination', {page: page})
  • post.*:单篇文章正文、元信息、上一篇/下一篇导航。
  • _partial/*:可抽象 headerfootersidebarmeta,提升复用。

3.3 常用变量与上下文

模板中常用:

变量 说明
site 站点对象(标题、文章列表、分类、标签)
page 当前页面对象(类型、路径、正文、Front Matter)
config _config.yml 内容
theme 主题 _config.yml 内容
url_for() 生成相对 / 绝对路径
date() 日期格式化
partial() 引用局部模板

3.4 国际化(i18n)处理

languages/zh-CN.yml 示例:

yaml
1
2
3
4
menu: home: 首页 archives: 归档 about: 关于

模板中调用:

ejs
1
2
3
4
<nav> <a href="/"> <%= __('menu.home') %> </a> <a href="/archives"> <%= __('menu.archives') %> </a> </nav>

3.5 静态资源与性能

最佳实践:

  • 样式分层:基础(base.css)+ 组件(component-*.css)+ 布局(layout.css)
  • 合理使用 hexo-helper 或构建工具(如仅在主题内使用简单打包脚本)
  • 图片使用相对路径,便于迁移;必要时接入自定义 CDN 配置项
  • 代码高亮:优先选择轻量方案(highlight.jsPrism

3.6 开发调试流程建议

bash
1
2
3
4
5
6
7
8
# 第一次开发,确认目录结构 hexo clean && hexo g && hexo s # 修改模板后快速验证(避免 public 残留) hexo clean && hexo g # 调试脚本(scripts/)加入日志 console.log('[my-theme] partial loaded')

3.7 通用注意事项与版本控制

  • 不直接修改 node_modules 中依赖,扩展放入 scripts/
  • 主题自身依赖写入 themes/my-theme/package.json,与站点根分离
  • 使用 git submodule 管理第三方主题便于升级
  • 保持模板语义化:使用 <main><article><nav> 提升可访问性与 SEO
  • 避免在模板中硬编码绝对 URL,使用 url_for() / config.url
  • 大型改动前 git branch feature/theme-i18n 分支化迭代
  • 渲染器选择:根据团队习惯选择 Pug / EJS / Nunjucks,保持统一避免混用降低可维护性
  • 常用渲染器插件一览:
    插件 用途
    hexo-renderer-pug 支持 Pug 模板
    hexo-renderer-ejs 支持 EJS 模板(部分版本内置)
    hexo-renderer-nunjucks 支持 Nunjucks 模板
    hexo-renderer-marked Markdown 渲染(可替换为 hexo-renderer-markdown-it
    hexo-renderer-stylus Stylus 预处理
    hexo-renderer-sass Sass/SCSS 支持(第三方)

关于插件开发:如需深入了解 Hexo 插件体系(过滤器、标签、生成器、部署器等)与自定义扩展开发,可参考本系列第二篇:HEXO 开发笔记(2)插件

参考

本文作者: 有次元袋的 tiger
本文链接: https://www.superheaoz.top/2024/12/58077/
版权声明: 本站点所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 我的个人天地