hexo 学习 0032:hexo 插件

Hexo 的核心魅力在于其强大的插件系统。你可以把它想象成手机的“应用商店”:核心系统是手机操作系统,而插件就是各种 APP。你不需要修改手机系统的底层代码(核心模块源码),只需安装相应的 APP(插件),就能轻松扩展拍照、导航等新功能。

在 Hexo 中,扩展功能主要有两种形式:脚本(Scripts)插件(Packages)。我们将深入讲解这两者的区别、制作方法以及官方工具的使用,最后教你如何将自己的作品发布到社区。

一、核心概念辨析:脚本 vs 插件

很多初学者容易混淆“脚本”和“插件”。简单来说,它们的区别在于复杂度分发方式

  • 脚本(Scripts)

    • 比喻:就像是你写在便签纸上的快捷指令,随拿随用。
    • 适用场景:逻辑简单、仅在当前博客项目中使用、不需要发布到 npm 供他人安装的代码。
    • 加载方式:Hexo 启动时会自动扫描并加载 scripts 文件夹下的所有 JavaScript 文件。
    • 优点:无需配置 package.json,开发速度极快。
  • 插件(Packages)

    • 比喻:就像是封装好的正式软件安装包,有说明书(package.json)和严格的目录结构。
    • 适用场景:逻辑复杂、需要复用、或者打算发布到 NPM 让其他 Hexo 用户安装的代码。
    • 加载方式:必须放在 node_modules 目录下,且文件夹名称必须以 hexo- 开头(这是 Hexo 识别插件的“暗号”)。
    • 优点:结构规范,依赖管理清晰,便于分发。

注意:如果你的代码只是想在自己博客里跑通一个小功能,选脚本;如果你想做一个通用的功能分享给社区,或者代码量很大需要模块化,选插件。

二、脚本(Scripts)开发指南

如果你决定使用脚本,操作非常简单。Hexo 会在初始化阶段自动读取项目根目录下的 scripts 文件夹。

1. 目录结构

在你的 Hexo 项目根目录下,确保存在 scripts 文件夹:

1
2
3
4
5
6
.
├── scripts
│ └── my-custom-script.js
├── source
├── themes
└── _config.yml

2. 编写示例

scripts/my-custom-script.js 中写入你的逻辑。Hexo 会将一个 hexo 对象作为参数传入。

1
2
3
4
5
6
7
8
// scripts/my-custom-script.js
hexo.extend.generator.register('my-generator', function(locals){
// 这里编写生成静态页面的逻辑
return {
path: 'hello.html',
data: '<h1>Hello Hexo Script!</h1>'
};
});

说明

  • hexo.extend.generator.register:注册一个生成器。
  • 'my-generator':生成器的名称,自定义即可。
  • function(locals):回调函数,locals 包含当前站点的所有数据(如文章、页面等)。
  • 只要保存文件,下次运行 hexo generatehexo server 时,该脚本就会自动生效,无需重启进程(在某些热重载模式下)。

三、插件(Packages)开发指南

开发插件需要遵循更严格的结构规范。这不仅是 Hexo 的要求,也是 Node.js 生态的标准。

1. 目录结构与命名规范

插件必须位于 node_modules 文件夹中,且文件夹名称必须以 hexo- 开头。如果名字不对,Hexo 会直接忽略它,就像门卫不认识通行证一样。

假设我们要开发一个叫 my-plugin 的插件,目录结构如下:

1
2
3
4
5
6
7
.
├── node_modules
│ └── hexo-my-plugin <-- 注意前缀 hexo-
│ ├── index.js <-- 主程序入口
│ └── package.json <-- 描述文件
├── source
└── _config.yml

2. 配置文件:package.json

package.json 是插件的身份证,描述了插件的名称、版本和入口文件。

示例内容 (node_modules/hexo-my-plugin/package.json):

1
2
3
4
5
{
"name": "hexo-my-plugin",
"version": "0.0.1",
"main": "index"
}

参数详解

  • name:必须是 hexo- 开头,且如果在 NPM 发布,全局名称必须唯一。
  • version:版本号,遵循语义化版本规范(如 0.0.1)。
  • main:指定入口文件,这里指向 index.js(后缀可省略)。

3. 主程序:index.js

这是插件的核心逻辑所在。

示例内容 (node_modules/hexo-my-plugin/index.js):

1
2
3
4
5
6
7
8
9
10
'use strict';

module.exports = function(hexo) {
// 注册一个标签插件
hexo.extend.tag.register('note', function(args, content) {
return '<div class="note">' + content + '</div>';
}, {ends: true});

hexo.log.info('Hexo My Plugin loaded successfully!');
};

说明

  • 模块导出一个函数,Hexo 会调用此函数并传入 hexo 实例。
  • hexo.extend.tag.register:注册一个自定义标签 {% note %}`。 * `{ends: true}`:表示这是一个成对标签,需要结束标记 `{% endnote %}

4. 激活插件

为了让 Hexo 检测并加载你在 node_modules 中手动创建的插件,你需要将其添加到项目根目录的 package.json 依赖项中。

操作:编辑 Hexo 项目根目录下的 package.json,在 dependencies 中加入你的插件名:

1
2
3
4
5
6
7
8
9
{
"name": "hexo-site",
"version": "0.0.0",
"private": true,
"dependencies": {
"hexo": "^5.0.0",
"hexo-my-plugin": "file:node_modules/hexo-my-plugin"
}
}

或者,如果你是通过 npm install 安装的远程插件,它会自动出现在这里。对于本地开发的插件,确保它在依赖列表中是关键步骤。

四、官方开发工具箱

Hexo 官方提供了一系列工具库,相当于给开发者提供的“瑞士军刀”,能极大加速开发过程。不要重复造轮子,善用这些工具:

  1. hexo-fs

    • 功能:文件系统 IO 操作。
    • 用途:用于读取、写入、删除文件或目录。它是对 Node.js 原生 fs 模块的 Promise 化封装,处理异步操作更方便。
    • 场景:当你需要读取本地图片、生成 sitemap 文件或备份数据时使用。
  2. hexo-util

    • 功能:通用工具程式。
    • 用途:包含字符串处理、URL 编码解码、HTML 转义、缓存处理等常用函数。
    • 场景:处理文章标题生成 slug、清理 HTML 标签、计算哈希值等。
  3. hexo-i18n

    • 功能:本地化(i18n)支持。
    • 用途:帮助插件支持多语言。你可以定义不同语言的翻译字典,根据用户的语言配置自动切换显示文本。
    • 场景:开发一个面向全球用户的主题或插件,需要显示“上一页”、“下一页”等多国语言文本时。
  4. hexo-pagination

    • 功能:生成分页数据。
    • 用途:将大量的文章列表切割成多页(Page 1, Page 2…),并计算每页的文章范围。
    • 场景:制作首页文章列表、归档页面、分类页面时需要分页功能。

五、命令与参数详解

在开发和发布过程中,你会频繁使用 Git 和 NPM 命令。以下是关键命令的详细拆解。

1. 克隆仓库 (git clone)

用于将远程代码库下载到本地。

命令格式

1
git clone <repository_url> [directory_name]

示例

1
$ git clone https://github.com/<username>/site.git

参数说明

  • https://github.com/<username>/site.git:远程仓库的 URL 地址。这是你要复刻(Fork)后的 hexo 官网文档仓库地址。
  • (可选)directory_name:如果不填,默认使用仓库名 site 作为文件夹名。

作用:将 hexo 官网的源代码完整复制到你的电脑当前目录下,以便你添加插件信息。

2. 安装依赖 (npm install)

用于安装项目所需的第三方包。

命令格式

1
npm install

简写npm i

示例

1
2
$ cd site
$ npm install

参数说明

  • 无额外参数时,默认读取当前目录下的 package.json 文件,安装其中 dependenciesdevDependencies 列出的所有包到 node_modules 文件夹。

作用:在提交插件列表更新前,必须确保本地环境拥有运行网站所需的所有依赖,防止构建失败。

3. 推送分支 (git push)

虽然素材中未给出具体 push 命令,但这是流程中必不可少的一步。

命令格式

1
git push origin <branch_name>

示例

1
$ git push origin add-my-plugin

参数说明

  • origin:远程仓库的别名,通常默认为 origin。
  • add-my-plugin:你本地创建并提交了更改的分支名称。

作用:将你本地修改的代码(新增的插件 YAML 文件)上传到你的 GitHub 远程仓库,为后续发起合并申请做准备。

六、发布插件到社区

当你的插件开发完成并测试无误后,可以将其发布到 Hexo 官方插件列表,让更多人使用。这个过程类似于向图书馆推荐一本新书。

发布步骤详解

第一步:复刻仓库 (Fork)
访问 hexojs/site 仓库,点击 GitHub 页面上的 “Fork” 按钮。这会在你的 GitHub 账号下创建一个该仓库的副本。

第二步:克隆与安装
将你 Fork 后的仓库克隆到本地,并安装依赖。

1
2
3
4
# 将 <username> 替换为你的 GitHub 用户名
$ git clone https://github.com/<username>/site.git
$ cd site
$ npm install
  • cd site:进入刚克隆下来的目录。
  • npm install:安装构建官网所需的 Node.js 依赖包。

第三步:创建插件描述文件
source/_data/plugins/ 目录下,创建一个新的 YAML 文件。文件名必须与你的插件名称一致

  • 假设你的插件叫 hexo-my-plugin
  • 新建文件路径:source/_data/plugins/hexo-my-plugin.yml

第四步:编辑描述文件
在刚才创建的 YAML 文件中填入插件信息。

示例内容 (source/_data/plugins/hexo-my-plugin.yml):

1
2
3
4
5
6
description: Server module for Hexo.
link: https://github.com/hexojs/hexo-server
tags:
- official
- server
- console

字段详解

  • description:简短描述插件的功能。例如 “Server module for Hexo” 表示这是 Hexo 的服务器模块。
  • link:插件的源代码仓库链接或主页链接,方便用户查看文档和源码。
  • tags:标签列表,用于分类检索。
    • official:如果是 Hexo 官方团队维护的插件,加上此标签。
    • serverconsole:描述插件类型的标签,如服务器相关、控制台命令相关。
    • 你可以根据插件特性自定义标签,如 seo, image, comment 等。

第五步:推送更改
将修改提交到 Git 并推送到你的远程仓库。

1
2
3
4
5
6
$ git add source/_data/plugins/hexo-my-plugin.yml
$ git commit -m "Add hexo-my-plugin to plugin list"
$ git push origin master
# 或者推送到你新建的特性分支
$ git checkout -b add-hexo-my-plugin
$ git push origin add-hexo-my-plugin

第六步:发起合并申请 (Pull Request)

  1. 打开你 Fork 的仓库页面。
  2. 点击 “Pull requests” 选项卡,然后点击 “New pull request”。
  3. 选择你推送了更改的分支作为源分支,目标分支通常是原仓库的 mastermain
  4. 填写标题和详细描述,说明你添加了什么插件,它的功能是什么。
  5. 提交申请。Hexo 维护者审核通过后,你的插件就会出现在官方插件列表中。

通过以上步骤,你就完成了一个 Hexo 插件从开发到发布的完整生命周期。记住,保持代码简洁、文档清晰,是获得社区认可的关键。